@hasna/contacts 0.6.23 → 0.6.28

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 (103) hide show
  1. package/README.md +61 -3
  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 +8605 -5889
  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 -79
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +4144 -4050
  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 +10963 -10178
  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 +23204 -20342
  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 +14 -3
  98. package/dist/db/feedback.d.ts +0 -15
  99. package/dist/db/feedback.d.ts.map +0 -1
  100. package/dist/db/remote-storage.d.ts +0 -14
  101. package/dist/db/remote-storage.d.ts.map +0 -1
  102. package/dist/db/remote-sync.d.ts +0 -49
  103. package/dist/db/remote-sync.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
@@ -69,9 +108,28 @@ PostgreSQL development URLs can disable TLS explicitly.
69
108
 
70
109
  By default, remote sync covers contacts, companies, tags, and the other
71
110
  non-sensitive relationship tables. `webhooks`, `contact_documents`, and
72
- `contact_health` are excluded until explicitly requested with `--tables`. Sync
73
- is a non-destructive merge: it inserts or updates rows and does not propagate
74
- deletes or tombstones.
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.
75
133
 
76
134
  `contacts cloud status`, `contacts cloud push`, `contacts cloud pull`, and
77
135
  `contacts cloud sync` remain compatibility aliases for the contacts-owned
@@ -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,CA03B3D"}
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,CA67B1D"}