@hasna/contacts 0.8.1 → 0.9.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 +10 -0
- package/dist/browser/cli.d.ts +4 -0
- package/dist/browser/cli.d.ts.map +1 -0
- package/dist/browser/identity.d.ts +3 -0
- package/dist/browser/identity.d.ts.map +1 -0
- package/dist/browser/install.d.ts +32 -0
- package/dist/browser/install.d.ts.map +1 -0
- package/dist/browser/native.d.ts +3 -0
- package/dist/browser/native.d.ts.map +1 -0
- package/dist/browser/native.js +822 -0
- package/dist/browser/protocol.d.ts +26 -0
- package/dist/browser/protocol.d.ts.map +1 -0
- package/dist/browser/values.d.ts +18 -0
- package/dist/browser/values.d.ts.map +1 -0
- package/dist/cli/commands/core.d.ts.map +1 -1
- package/dist/cli/index.js +408 -127
- package/dist/cli/status-domain.preload.d.ts +1 -1
- package/dist/cli/status-domain.preload.d.ts.map +1 -1
- package/dist/cli/status-fixture.d.ts +17 -0
- package/dist/cli/status-fixture.d.ts.map +1 -0
- package/dist/index.js +43 -4
- package/dist/lib/audience-contract.d.ts +9 -9
- package/dist/lib/compact-output.d.ts +67 -0
- package/dist/lib/compact-output.d.ts.map +1 -0
- package/dist/mcp/handlers/core.d.ts.map +1 -1
- package/dist/mcp/index.d.ts +2 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +378 -194
- package/dist/mcp/profile.d.ts +8 -0
- package/dist/mcp/profile.d.ts.map +1 -0
- package/dist/mcp/register-tools.d.ts +3 -1
- package/dist/mcp/register-tools.d.ts.map +1 -1
- package/dist/mcp/storage-tools.d.ts +2 -1
- package/dist/mcp/storage-tools.d.ts.map +1 -1
- package/dist/mcp/tools.d.ts +7 -45
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/sdk/index.js +1 -1
- package/dist/server/index.js +30 -16
- package/dist/server/pg-store.d.ts +1 -0
- package/dist/server/pg-store.d.ts.map +1 -1
- package/dist/store/index.d.ts.map +1 -1
- package/docs/chrome-autofill.md +45 -0
- package/extension/background.js +284 -0
- package/extension/content.js +387 -0
- package/extension/detect.js +228 -0
- package/extension/fill.js +112 -0
- package/extension/icons/128.png +0 -0
- package/extension/icons/16.png +0 -0
- package/extension/icons/32.png +0 -0
- package/extension/icons/48.png +0 -0
- package/extension/icons/icon.svg +17 -0
- package/extension/manifest.json +54 -0
- package/extension/popup.css +78 -0
- package/extension/popup.html +47 -0
- package/extension/popup.js +166 -0
- package/package.json +9 -5
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
export {};
|
|
2
2
|
//# sourceMappingURL=status-domain.preload.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status-domain.preload.d.ts","sourceRoot":"","sources":["../../src/cli/status-domain.preload.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"status-domain.preload.d.ts","sourceRoot":"","sources":["../../src/cli/status-domain.preload.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type StatusFixtureMode = "unconfigured" | "failure" | "success";
|
|
2
|
+
export declare const fixtureStation = "contacts-status-fixture";
|
|
3
|
+
export declare const envFixtureKey = "status-fixture-key";
|
|
4
|
+
export declare const diskFixtureKey = "disk-key-not-a-real-secret";
|
|
5
|
+
export declare function statusFixtureEnv(): Record<string, string>;
|
|
6
|
+
export declare function statusFixtureCommand(home: string, command: string[]): string[];
|
|
7
|
+
export declare function runStatusFixture(args: string[], env: Record<string, string>, mode?: StatusFixtureMode): {
|
|
8
|
+
exitCode: number | null;
|
|
9
|
+
pid: number;
|
|
10
|
+
output: (string | null)[];
|
|
11
|
+
stdout: string;
|
|
12
|
+
stderr: string;
|
|
13
|
+
status: number | null;
|
|
14
|
+
signal: NodeJS.Signals | null;
|
|
15
|
+
error?: Error;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=status-fixture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-fixture.d.ts","sourceRoot":"","sources":["../../src/cli/status-fixture.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,SAAS,GAAG,SAAS,CAAC;AACvE,eAAO,MAAM,cAAc,4BAA4B,CAAC;AACxD,eAAO,MAAM,aAAa,uBAAuB,CAAC;AAClD,eAAO,MAAM,cAAc,+BAA+B,CAAC;AAE3D,wBAAgB,gBAAgB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWzD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAuB9E;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,GAAE,iBAAkC;;;;;;;;;EAYrH"}
|
package/dist/index.js
CHANGED
|
@@ -316,6 +316,39 @@ function stripUndefined(input) {
|
|
|
316
316
|
return out;
|
|
317
317
|
}
|
|
318
318
|
|
|
319
|
+
class ContactsApiResponseError extends Error {
|
|
320
|
+
constructor(operation, detail) {
|
|
321
|
+
super(`contacts: malformed /v1 response for ${operation}: ${detail}`);
|
|
322
|
+
this.name = "ContactsApiResponseError";
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
function requireAppendedContact(response, contactId, collection, matchKey, value) {
|
|
326
|
+
const operation = collection === "emails" ? "addEmailToContact" : "addPhoneToContact";
|
|
327
|
+
const contact = pick(response, "contact");
|
|
328
|
+
if (!contact || typeof contact !== "object" || Array.isArray(contact)) {
|
|
329
|
+
throw new ContactsApiResponseError(operation, "expected an object at response.contact");
|
|
330
|
+
}
|
|
331
|
+
if (contact.id !== contactId) {
|
|
332
|
+
throw new ContactsApiResponseError(operation, "response.contact.id did not match the requested contact");
|
|
333
|
+
}
|
|
334
|
+
const items = contact[collection];
|
|
335
|
+
if (!Array.isArray(items)) {
|
|
336
|
+
throw new ContactsApiResponseError(operation, `response.contact.${collection} was not an array`);
|
|
337
|
+
}
|
|
338
|
+
const normalize = collection === "emails" ? (input) => input.toLowerCase() : (input) => input;
|
|
339
|
+
const wanted = normalize(value);
|
|
340
|
+
const appended = items.find((item) => {
|
|
341
|
+
if (!item || typeof item !== "object" || Array.isArray(item))
|
|
342
|
+
return false;
|
|
343
|
+
const record = item;
|
|
344
|
+
return typeof record.id === "string" && record.contact_id === contactId && typeof record[matchKey] === "string" && normalize(record[matchKey]) === wanted;
|
|
345
|
+
});
|
|
346
|
+
if (!appended) {
|
|
347
|
+
throw new ContactsApiResponseError(operation, `response.contact.${collection} did not contain the requested value`);
|
|
348
|
+
}
|
|
349
|
+
return contact;
|
|
350
|
+
}
|
|
351
|
+
|
|
319
352
|
class ApiStore {
|
|
320
353
|
client;
|
|
321
354
|
mode = "api";
|
|
@@ -385,11 +418,17 @@ class ApiStore {
|
|
|
385
418
|
async mergeContacts() {
|
|
386
419
|
return unavailable("mergeContacts");
|
|
387
420
|
}
|
|
388
|
-
async addEmailToContact() {
|
|
389
|
-
|
|
421
|
+
async addEmailToContact(contactId, email) {
|
|
422
|
+
const res = await this.patch(`/contacts/${this.enc(contactId)}`, {
|
|
423
|
+
emails_add: [stripUndefined(email)]
|
|
424
|
+
});
|
|
425
|
+
return requireAppendedContact(res, contactId, "emails", "address", email.address);
|
|
390
426
|
}
|
|
391
|
-
async addPhoneToContact() {
|
|
392
|
-
|
|
427
|
+
async addPhoneToContact(contactId, phone) {
|
|
428
|
+
const res = await this.patch(`/contacts/${this.enc(contactId)}`, {
|
|
429
|
+
phones_add: [stripUndefined(phone)]
|
|
430
|
+
});
|
|
431
|
+
return requireAppendedContact(res, contactId, "phones", "number", phone.number);
|
|
393
432
|
}
|
|
394
433
|
async archiveContact() {
|
|
395
434
|
return unavailable("archiveContact");
|
|
@@ -19,8 +19,8 @@ export declare const AudiencePredicateContractSchema: z.ZodEffects<z.ZodObject<{
|
|
|
19
19
|
values: z.ZodDefault<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>, "many">>;
|
|
20
20
|
}, "strict", z.ZodTypeAny, {
|
|
21
21
|
values: (string | number | boolean)[];
|
|
22
|
-
kind: "tag" | "attribute" | "group";
|
|
23
22
|
op: "eq" | "neq" | "in" | "not_in" | "exists" | "not_exists";
|
|
23
|
+
kind: "tag" | "attribute" | "group";
|
|
24
24
|
key?: string | undefined;
|
|
25
25
|
value?: string | number | boolean | undefined;
|
|
26
26
|
}, {
|
|
@@ -31,8 +31,8 @@ export declare const AudiencePredicateContractSchema: z.ZodEffects<z.ZodObject<{
|
|
|
31
31
|
op?: "eq" | "neq" | "in" | "not_in" | "exists" | "not_exists" | undefined;
|
|
32
32
|
}>, {
|
|
33
33
|
values: (string | number | boolean)[];
|
|
34
|
-
kind: "tag" | "attribute" | "group";
|
|
35
34
|
op: "eq" | "neq" | "in" | "not_in" | "exists" | "not_exists";
|
|
35
|
+
kind: "tag" | "attribute" | "group";
|
|
36
36
|
key?: string | undefined;
|
|
37
37
|
value?: string | number | boolean | undefined;
|
|
38
38
|
}, {
|
|
@@ -52,8 +52,8 @@ export declare const AudienceDefinitionContractSchema: z.ZodObject<{
|
|
|
52
52
|
values: z.ZodDefault<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>, "many">>;
|
|
53
53
|
}, "strict", z.ZodTypeAny, {
|
|
54
54
|
values: (string | number | boolean)[];
|
|
55
|
-
kind: "tag" | "attribute" | "group";
|
|
56
55
|
op: "eq" | "neq" | "in" | "not_in" | "exists" | "not_exists";
|
|
56
|
+
kind: "tag" | "attribute" | "group";
|
|
57
57
|
key?: string | undefined;
|
|
58
58
|
value?: string | number | boolean | undefined;
|
|
59
59
|
}, {
|
|
@@ -64,8 +64,8 @@ export declare const AudienceDefinitionContractSchema: z.ZodObject<{
|
|
|
64
64
|
op?: "eq" | "neq" | "in" | "not_in" | "exists" | "not_exists" | undefined;
|
|
65
65
|
}>, {
|
|
66
66
|
values: (string | number | boolean)[];
|
|
67
|
-
kind: "tag" | "attribute" | "group";
|
|
68
67
|
op: "eq" | "neq" | "in" | "not_in" | "exists" | "not_exists";
|
|
68
|
+
kind: "tag" | "attribute" | "group";
|
|
69
69
|
key?: string | undefined;
|
|
70
70
|
value?: string | number | boolean | undefined;
|
|
71
71
|
}, {
|
|
@@ -79,8 +79,8 @@ export declare const AudienceDefinitionContractSchema: z.ZodObject<{
|
|
|
79
79
|
match: "all" | "any";
|
|
80
80
|
predicates: {
|
|
81
81
|
values: (string | number | boolean)[];
|
|
82
|
-
kind: "tag" | "attribute" | "group";
|
|
83
82
|
op: "eq" | "neq" | "in" | "not_in" | "exists" | "not_exists";
|
|
83
|
+
kind: "tag" | "attribute" | "group";
|
|
84
84
|
key?: string | undefined;
|
|
85
85
|
value?: string | number | boolean | undefined;
|
|
86
86
|
}[];
|
|
@@ -113,8 +113,8 @@ export declare const AudienceContractSchema: z.ZodObject<{
|
|
|
113
113
|
values: z.ZodDefault<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>, "many">>;
|
|
114
114
|
}, "strict", z.ZodTypeAny, {
|
|
115
115
|
values: (string | number | boolean)[];
|
|
116
|
-
kind: "tag" | "attribute" | "group";
|
|
117
116
|
op: "eq" | "neq" | "in" | "not_in" | "exists" | "not_exists";
|
|
117
|
+
kind: "tag" | "attribute" | "group";
|
|
118
118
|
key?: string | undefined;
|
|
119
119
|
value?: string | number | boolean | undefined;
|
|
120
120
|
}, {
|
|
@@ -125,8 +125,8 @@ export declare const AudienceContractSchema: z.ZodObject<{
|
|
|
125
125
|
op?: "eq" | "neq" | "in" | "not_in" | "exists" | "not_exists" | undefined;
|
|
126
126
|
}>, {
|
|
127
127
|
values: (string | number | boolean)[];
|
|
128
|
-
kind: "tag" | "attribute" | "group";
|
|
129
128
|
op: "eq" | "neq" | "in" | "not_in" | "exists" | "not_exists";
|
|
129
|
+
kind: "tag" | "attribute" | "group";
|
|
130
130
|
key?: string | undefined;
|
|
131
131
|
value?: string | number | boolean | undefined;
|
|
132
132
|
}, {
|
|
@@ -140,8 +140,8 @@ export declare const AudienceContractSchema: z.ZodObject<{
|
|
|
140
140
|
match: "all" | "any";
|
|
141
141
|
predicates: {
|
|
142
142
|
values: (string | number | boolean)[];
|
|
143
|
-
kind: "tag" | "attribute" | "group";
|
|
144
143
|
op: "eq" | "neq" | "in" | "not_in" | "exists" | "not_exists";
|
|
144
|
+
kind: "tag" | "attribute" | "group";
|
|
145
145
|
key?: string | undefined;
|
|
146
146
|
value?: string | number | boolean | undefined;
|
|
147
147
|
}[];
|
|
@@ -167,8 +167,8 @@ export declare const AudienceContractSchema: z.ZodObject<{
|
|
|
167
167
|
match: "all" | "any";
|
|
168
168
|
predicates: {
|
|
169
169
|
values: (string | number | boolean)[];
|
|
170
|
-
kind: "tag" | "attribute" | "group";
|
|
171
170
|
op: "eq" | "neq" | "in" | "not_in" | "exists" | "not_exists";
|
|
171
|
+
kind: "tag" | "attribute" | "group";
|
|
172
172
|
key?: string | undefined;
|
|
173
173
|
value?: string | number | boolean | undefined;
|
|
174
174
|
}[];
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ContactWithDetails } from "../types/index.js";
|
|
2
|
+
export declare const CONTACTS_COMPACT_LIMIT = 20;
|
|
3
|
+
export declare const CONTACTS_MAX_LIMIT = 500;
|
|
4
|
+
export declare function normalizeContactsLimit(value: unknown, fallback?: number): number;
|
|
5
|
+
export declare function normalizeContactsOffset(value: unknown): number;
|
|
6
|
+
export declare function summarizeContact(contact: ContactWithDetails): {
|
|
7
|
+
id: string;
|
|
8
|
+
display_name: string;
|
|
9
|
+
job_title: string | null;
|
|
10
|
+
company: {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
} | null;
|
|
14
|
+
primary_email: string;
|
|
15
|
+
primary_phone: string;
|
|
16
|
+
status: import("../index.js").ContactStatus;
|
|
17
|
+
follow_up_at: string | null;
|
|
18
|
+
last_contacted_at: string | null;
|
|
19
|
+
archived: boolean;
|
|
20
|
+
sensitivity: import("../index.js").Sensitivity;
|
|
21
|
+
tags: {
|
|
22
|
+
id: string;
|
|
23
|
+
name: string;
|
|
24
|
+
}[];
|
|
25
|
+
updated_at: string;
|
|
26
|
+
};
|
|
27
|
+
export declare function compareContactsByDisplayNameAndId(left: Pick<ContactWithDetails, "display_name" | "id">, right: Pick<ContactWithDetails, "display_name" | "id">): number;
|
|
28
|
+
export declare function compactContactsPage(contacts: ContactWithDetails[], options: {
|
|
29
|
+
total: number;
|
|
30
|
+
limit: number;
|
|
31
|
+
offset: number;
|
|
32
|
+
}): {
|
|
33
|
+
contacts: {
|
|
34
|
+
id: string;
|
|
35
|
+
display_name: string;
|
|
36
|
+
job_title: string | null;
|
|
37
|
+
company: {
|
|
38
|
+
id: string;
|
|
39
|
+
name: string;
|
|
40
|
+
} | null;
|
|
41
|
+
primary_email: string;
|
|
42
|
+
primary_phone: string;
|
|
43
|
+
status: import("../index.js").ContactStatus;
|
|
44
|
+
follow_up_at: string | null;
|
|
45
|
+
last_contacted_at: string | null;
|
|
46
|
+
archived: boolean;
|
|
47
|
+
sensitivity: import("../index.js").Sensitivity;
|
|
48
|
+
tags: {
|
|
49
|
+
id: string;
|
|
50
|
+
name: string;
|
|
51
|
+
}[];
|
|
52
|
+
updated_at: string;
|
|
53
|
+
}[];
|
|
54
|
+
count: number;
|
|
55
|
+
total: number;
|
|
56
|
+
limit: number;
|
|
57
|
+
cursor: number;
|
|
58
|
+
next_cursor: number | null;
|
|
59
|
+
has_more: boolean;
|
|
60
|
+
compact: true;
|
|
61
|
+
sort: {
|
|
62
|
+
fields: string[];
|
|
63
|
+
direction: "asc";
|
|
64
|
+
};
|
|
65
|
+
hint: string;
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=compact-output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compact-output.d.ts","sourceRoot":"","sources":["../../src/lib/compact-output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,SAAyB,GAAG,MAAM,CAIhG;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAI9D;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,kBAAkB;;;;;;;;;;;;;;;;;;;;EAgB3D;AAED,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,IAAI,CAAC,kBAAkB,EAAE,cAAc,GAAG,IAAI,CAAC,EACrD,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,cAAc,GAAG,IAAI,CAAC,GACrD,MAAM,CAER;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,kBAAkB,EAAE,EAC9B,OAAO,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkB1D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../src/mcp/handlers/core.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../src/mcp/handlers/core.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA4C9C,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CA0YpD,CAAC"}
|
package/dist/mcp/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
-
|
|
3
|
+
import { type ContactsMcpProfile } from "./profile.js";
|
|
4
|
+
export declare function buildServer(profile?: ContactsMcpProfile): McpServer;
|
|
4
5
|
/**
|
|
5
6
|
* Classify early-exit arguments before any http-mode parse, server build, or
|
|
6
7
|
* stdio bind. `--help` / `--version` answer with rc=0 and the MCP server never
|
package/dist/mcp/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMpE,OAAO,EAA6B,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAYlF,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAA2B,GAAG,SAAS,CAQ3E;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAI5E;AAED,wBAAgB,QAAQ,IAAI,MAAM,CAWjC;AA4CD,wBAAgB,gBAAgB,CAAC,KAAK,SAAkB,GAAG,OAAO,CAIjE"}
|