@hasna/contacts 0.6.36 → 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 +53 -69
- package/dist/cli/commands/advanced.d.ts.map +1 -1
- package/dist/cli/commands/core.d.ts +1 -1
- package/dist/cli/commands/core.d.ts.map +1 -1
- package/dist/cli/commands/crm.d.ts.map +1 -1
- package/dist/cli/index.js +9158 -39958
- package/dist/cli/legacy.d.ts +18 -0
- package/dist/cli/legacy.d.ts.map +1 -0
- package/dist/cli/status-domain.preload.d.ts +2 -0
- package/dist/cli/status-domain.preload.d.ts.map +1 -0
- package/dist/cli/storage.d.ts.map +1 -1
- package/dist/cloud/client-config.d.ts +6 -0
- package/dist/cloud/client-config.d.ts.map +1 -0
- package/dist/cloud/http-storage.d.ts +40 -69
- package/dist/cloud/http-storage.d.ts.map +1 -1
- package/dist/db/paths.d.ts +13 -7
- package/dist/db/paths.d.ts.map +1 -1
- package/dist/generated/storage-kit/index.d.ts +0 -1
- package/dist/generated/storage-kit/index.d.ts.map +1 -1
- package/dist/generated/storage-kit/pool.d.ts +13 -3
- package/dist/generated/storage-kit/pool.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +373 -5713
- package/dist/lib/images.d.ts.map +1 -1
- package/dist/mcp/handlers/advanced.d.ts.map +1 -1
- package/dist/mcp/handlers/core.d.ts +1 -1
- package/dist/mcp/index.js +461 -5901
- package/dist/mcp/storage-tools.d.ts.map +1 -1
- package/dist/sdk/index.d.ts +15 -13
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/index.js +44 -1
- package/dist/server/cloud.d.ts +6 -7
- package/dist/server/cloud.d.ts.map +1 -1
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +3744 -35305
- package/dist/server/security.d.ts +1 -1
- package/dist/server/security.d.ts.map +1 -1
- package/dist/server/serve.d.ts.map +1 -1
- package/dist/store/index.d.ts +66 -93
- package/dist/store/index.d.ts.map +1 -1
- package/dist/types/store-dto.d.ts +273 -0
- package/dist/types/store-dto.d.ts.map +1 -0
- package/hasna.contract.json +63 -10
- package/package.json +23 -14
- package/dashboard/dist/assets/index-0l6aQb1t.css +0 -1
- package/dashboard/dist/assets/index-opnZdkVD.js +0 -229
- package/dashboard/dist/index.html +0 -13
- package/dist/generated/storage-kit/mode.d.ts +0 -48
- package/dist/generated/storage-kit/mode.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @hasna/contacts
|
|
2
2
|
|
|
3
|
-
Contact management for AI coding agents — CLI + MCP +
|
|
3
|
+
Contact management for AI coding agents — CLI + MCP + authenticated HTTP API
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@hasna/contacts)
|
|
6
6
|
[](LICENSE)
|
|
@@ -11,12 +11,38 @@ Contact management for AI coding agents — CLI + MCP + Web
|
|
|
11
11
|
npm install -g @hasna/contacts
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
+
## Configure the client
|
|
15
|
+
|
|
16
|
+
Every CLI, MCP, and package data operation uses one authenticated HTTPS `/v1`
|
|
17
|
+
authority. There is no built-in hosted URL and no local database fallback.
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
export HASNA_CONTACTS_API_URL="https://contacts.example.com"
|
|
21
|
+
# Provision the API key through the @hasna/contracts credential chain. For
|
|
22
|
+
# example, put HASNA_CONTACTS_API_KEY in the shared fleet/config credential chain,
|
|
23
|
+
# or configure HASNA_CONTACTS_API_KEY_REF for the secrets client.
|
|
24
|
+
contacts connection --json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
An absent or invalid URL/key fails closed. `HASNA_CONTACTS_STORAGE_MODE`,
|
|
28
|
+
`CONTACTS_STORAGE_MODE`, contacts DB-path variables, and contacts database URLs
|
|
29
|
+
are rejected in client processes. PostgreSQL URLs belong only to
|
|
30
|
+
`contacts-serve` and the migration task.
|
|
31
|
+
|
|
14
32
|
## CLI Usage
|
|
15
33
|
|
|
16
34
|
```bash
|
|
35
|
+
contacts status # CLI version, API endpoint, storage mode, record counts
|
|
36
|
+
contacts status --json
|
|
17
37
|
contacts --help
|
|
18
38
|
```
|
|
19
39
|
|
|
40
|
+
`contacts status` answers even on a box without an API key: an unconfigured
|
|
41
|
+
client reports storage `unconfigured` (a failed request on a configured box
|
|
42
|
+
reports storage `error` with the failure message) instead of crashing, so
|
|
43
|
+
agents can observe the configuration drift the command exists to expose.
|
|
44
|
+
|
|
45
|
+
|
|
20
46
|
## Audiences, consent, and suppression
|
|
21
47
|
|
|
22
48
|
Audience segments implement the `hasna.audience.v1` contract (distribution
|
|
@@ -63,7 +89,7 @@ MCP_HTTP=1 contacts-mcp
|
|
|
63
89
|
- Health: `GET http://127.0.0.1:8809/health`
|
|
64
90
|
- MCP: `http://127.0.0.1:8809/mcp`
|
|
65
91
|
|
|
66
|
-
The REST server
|
|
92
|
+
The REST server is a separate authenticated `/v1` surface.
|
|
67
93
|
|
|
68
94
|
## REST API
|
|
69
95
|
|
|
@@ -72,83 +98,41 @@ contacts-serve
|
|
|
72
98
|
```
|
|
73
99
|
|
|
74
100
|
`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
|
-
|
|
77
|
-
|
|
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.
|
|
101
|
+
`CONTACTS_HOST=<host>` only when intentionally exposing it beyond loopback. The
|
|
102
|
+
server requires PostgreSQL configuration and API-key signing configuration;
|
|
103
|
+
readiness fails closed when either is unavailable.
|
|
85
104
|
|
|
86
|
-
## Storage
|
|
105
|
+
## Storage and legacy data
|
|
87
106
|
|
|
88
|
-
|
|
89
|
-
|
|
107
|
+
The client never opens SQLite or PostgreSQL. The server owns PostgreSQL and all
|
|
108
|
+
authoritative data remains server-side. Inspect the value-free connection state
|
|
109
|
+
with:
|
|
90
110
|
|
|
91
111
|
```bash
|
|
92
|
-
contacts
|
|
93
|
-
contacts storage status --json
|
|
94
|
-
contacts storage push --tables contacts,companies
|
|
95
|
-
contacts storage pull --tables contacts,companies
|
|
96
|
-
contacts storage sync
|
|
112
|
+
contacts connection --json
|
|
97
113
|
```
|
|
98
114
|
|
|
99
|
-
|
|
115
|
+
Retired local databases are never auto-adopted or silently ignored. The
|
|
116
|
+
explicit migration aid only inspects and copies them; it never opens, changes,
|
|
117
|
+
deletes, or selects one as the live store:
|
|
100
118
|
|
|
101
119
|
```bash
|
|
102
|
-
|
|
103
|
-
|
|
120
|
+
contacts legacy inspect --json
|
|
121
|
+
contacts legacy preserve --source /exact/path/contacts.db \
|
|
122
|
+
--output /existing/directory/contacts.db.pre-https.20260901
|
|
104
123
|
```
|
|
105
124
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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.
|
|
139
|
-
|
|
140
|
-
## Data Directory
|
|
141
|
-
|
|
142
|
-
On-box data resolves through the XDG dirs per `@hasna/paths`:
|
|
143
|
-
|
|
144
|
-
- documents, the SQLite store, `config.json` and the vault config live in the
|
|
145
|
-
**XDG data root**: `~/.local/share/hasna/contacts/` (or `$HASNA_DATA_HOME/contacts`).
|
|
146
|
-
- the vault session state lives in the **XDG state root**:
|
|
147
|
-
`~/.local/state/hasna/contacts/` (or `$HASNA_STATE_HOME/contacts`).
|
|
148
|
-
|
|
149
|
-
The legacy `~/.hasna/contacts/` home is never written to; on first use any
|
|
150
|
-
pre-existing legacy store is adopted into the XDG roots (never clobbering an
|
|
151
|
-
existing XDG store).
|
|
125
|
+
If a SQLite WAL, journal, or shared-memory sidecar is present, preservation
|
|
126
|
+
refuses to proceed until every legacy process is stopped and the old client has checkpointed the database. To move
|
|
127
|
+
portable contact records, use a legacy release against the preserved copy to
|
|
128
|
+
export JSON, then run `contacts import exported.json` with the HTTPS client
|
|
129
|
+
configured. Existing files are never overwritten.
|
|
130
|
+
|
|
131
|
+
Preservation rejects source, ancestor, or output replacement races and verifies
|
|
132
|
+
the copied bytes with SHA-256 and stable output metadata before success. If a copy
|
|
133
|
+
fails after output creation, any private partial output is left untouched and
|
|
134
|
+
reported as unverified for manual inspection; the command never deletes a
|
|
135
|
+
pathname that another process might have replaced.
|
|
152
136
|
|
|
153
137
|
## License
|
|
154
138
|
|
|
@@ -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;
|
|
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;AAiBzC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAq5B/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;
|
|
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;AAqBzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAg4B5E"}
|
|
@@ -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;AAezC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
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,CAi+B1D"}
|