@ghostpaw/affinity 0.4.0 → 0.5.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 +174 -99
- package/SKILL.md +217 -33
- package/dist/cli.js +2471 -927
- package/dist/index.cjs +1410 -493
- package/dist/index.d.cts +556 -55
- package/dist/index.d.ts +556 -55
- package/dist/index.js +1410 -493
- package/dist/mcp-server.js +1845 -704
- package/dist/mcp.cjs +1631 -609
- package/dist/mcp.js +1632 -610
- package/package.json +1 -1
- package/skills/affinity/SKILL.md +217 -33
package/SKILL.md
CHANGED
|
@@ -2,24 +2,69 @@
|
|
|
2
2
|
name: affinity
|
|
3
3
|
description: "Search and maintain local contacts, identities, relationships, events, commitments, and recurring dates. Use when recording relationship evidence or reviewing a social CRM."
|
|
4
4
|
license: "MIT"
|
|
5
|
-
compatibility: "
|
|
5
|
+
compatibility: "The release binary needs no runtime. MCP stdio or ghostpaw-affinity CLI."
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# affinity
|
|
9
9
|
|
|
10
|
+
## CLI cheat sheet
|
|
11
|
+
|
|
12
|
+
Install: `curl -fsSL https://raw.githubusercontent.com/GhostPawJS/affinity/main/install.sh | sh`
|
|
13
|
+
Windows: `irm https://raw.githubusercontent.com/GhostPawJS/affinity/main/install.ps1 | iex`
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
export GHOSTPAW_AFFINITY_DB=/abs/path/affinity.db
|
|
17
|
+
# Or --db; default ~/.ghostpaw/affinity.db. Piped output is JSON; --compact omits empty receipt arrays.
|
|
18
|
+
# Exit: 0 ok/no_op, 1 tool error, 2 usage/invalid input, 3 not found/clarification, 4 conflict, 70 internal.
|
|
19
|
+
# Dates: epoch ms, ISO with offset/Z, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, +3d, -2d.
|
|
20
|
+
# Date-only occurredAt uses local midnight; dueAt uses local end of day.
|
|
21
|
+
ghostpaw-affinity contact create '{"name":"Fox","kind":"human","bootstrapOwner":true}'
|
|
22
|
+
ghostpaw-affinity search "Jana" # Search names, identities, tags, attributes, roles and events before creating.
|
|
23
|
+
ghostpaw-affinity contact create '{"name":"Jana Petersen","kind":"human"}'
|
|
24
|
+
ghostpaw-affinity identity add --contact '{"contactId":2}' --input '{"type":"email","value":"jana@x.de"}'
|
|
25
|
+
ghostpaw-affinity relationship tie --from '{"contactId":2}' --to '{"contactId":3}' --kind works_at --role Founder
|
|
26
|
+
ghostpaw-affinity relationship add --from '{"contactId":1}' --to '{"contactId":2}' --kind professional --role lead
|
|
27
|
+
ghostpaw-affinity event record --kind interaction --input '{"type":"conversation","occurredAt":"today","summary":"Call re pilot","significance":6,"participants":[{"contactId":2,"role":"recipient","directionality":"mutual"}]}'
|
|
28
|
+
ghostpaw-affinity commitment record --input '{"commitmentType":"promise","occurredAt":"today","dueAt":"+3d","summary":"Send proposal","significance":6,"participants":[{"contactId":2,"role":"recipient"}]}'
|
|
29
|
+
ghostpaw-affinity commitment resolve --commitment-event-id 6 --resolution kept
|
|
30
|
+
ghostpaw-affinity date add --input '{"target":{"kind":"contact","contact":{"contactId":2}},"recurrenceKind":"birthday","anchorMonth":11,"anchorDay":3,"summary":"Jana bday","significance":4}'
|
|
31
|
+
ghostpaw-affinity attribute set --target '{"kind":"contact","contact":{"contactId":2}}' --name pipeline_stage --value '"proposal"'
|
|
32
|
+
ghostpaw-affinity attribute set --target '{"kind":"contact","contact":{"contactId":2}}' --name tag:gastro-radar --value null
|
|
33
|
+
ghostpaw-affinity show contact_profile --contact '{"contactId":2}'
|
|
34
|
+
ghostpaw-affinity review events.contact_journal --contact '{"contactId":2}'
|
|
35
|
+
ghostpaw-affinity review links.radar
|
|
36
|
+
ghostpaw-affinity review commitments.open
|
|
37
|
+
ghostpaw-affinity review dates.upcoming --horizon-days 14
|
|
38
|
+
ghostpaw-affinity review contacts.list --tag gastro-radar
|
|
39
|
+
ghostpaw-affinity review contacts.list --attribute pipeline_stage=proposal
|
|
40
|
+
ghostpaw-affinity review contacts.duplicates
|
|
41
|
+
ghostpaw-affinity contact merge --winner '{"contactId":2}' --loser '{"contactId":8}' --reason-summary "same person"
|
|
42
|
+
ghostpaw-affinity duplicate dismiss --left '{"contactId":5}' --right '{"contactId":10}' --reason '"different people"'
|
|
43
|
+
ghostpaw-affinity contact revise '{"contactId":3}' --patch '{"name":"New Name"}'
|
|
44
|
+
ghostpaw-affinity contact lifecycle '{"contactId":9}' dormant
|
|
45
|
+
ghostpaw-affinity relationship state --link '{"linkId":7}' --state dormant
|
|
46
|
+
ghostpaw-affinity contact export --contact '{"contactId":2}'
|
|
47
|
+
ghostpaw-affinity contact delete --contact '{"contactId":2}' --confirm
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
For bots and agents: run `ghostpaw-affinity mcp` for MCP stdio, or use this CLI with `--json`. Read a guide with `ghostpaw-affinity skill <guide>`.
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
## Appendix: MCP and tool calls
|
|
54
|
+
|
|
10
55
|
Affinity is a local relationship model and social CRM. Search before creating contacts. Inspect before revising or merging. Record direct evidence honestly, keep identities and structural ties distinct from social links, and ask for clarification when a target is ambiguous. Review commitments and recurring dates regularly. Derived scores guide attention and do not prove relationship quality.
|
|
11
56
|
|
|
12
|
-
|
|
57
|
+
### Calling tools
|
|
13
58
|
|
|
14
59
|
MCP: connect to ghostpaw-affinity, then call a tool by name with its JSON arguments.
|
|
15
60
|
|
|
16
|
-
CLI: `ghostpaw-affinity call <tool> '<JSON object>'` or `ghostpaw-affinity <tool> --parameter value
|
|
61
|
+
CLI: `ghostpaw-affinity call <tool> '<JSON object>'` or `ghostpaw-affinity <tool> --parameter value`.
|
|
17
62
|
|
|
18
63
|
Inspect schemas with `ghostpaw-affinity describe <tool>`. Use `--db <path>` to select a database.
|
|
19
64
|
|
|
20
|
-
|
|
65
|
+
### search_affinity
|
|
21
66
|
|
|
22
|
-
Search contacts by name
|
|
67
|
+
Search contacts by name, identity, attributes, link roles, bonds and event text. All whitespace tokens must match. Dormant and lost contacts are excluded by default; use includeDormant and includeLost to include them.
|
|
23
68
|
|
|
24
69
|
Use when: Use this when you want to find contacts from free text or a known routing identity such as an email or URL-like handle.
|
|
25
70
|
|
|
@@ -32,12 +77,19 @@ Read-only.
|
|
|
32
77
|
| query | string | yes | Free-text or natural-key query. |
|
|
33
78
|
| kind | string | no | human, group, company, team, pet, service, other. Optional contact kind filter. |
|
|
34
79
|
| lifecycleState | string | no | active, dormant, merged, lost. Optional lifecycle state filter. |
|
|
80
|
+
| attribute | string / array | no | |
|
|
81
|
+
| tag | string / array | no | |
|
|
82
|
+
| includeLost | boolean | no | Include lost contacts (search excludes them by default). |
|
|
35
83
|
| includeOwner | boolean | no | Whether owner contacts are included. |
|
|
36
84
|
| includeDormant | boolean | no | Whether dormant contacts are included. |
|
|
37
85
|
| limit | integer | no | Optional result limit. |
|
|
38
86
|
| offset | integer | no | Optional result offset. |
|
|
39
87
|
|
|
40
|
-
|
|
88
|
+
```sh
|
|
89
|
+
ghostpaw-affinity search "Jana"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### review_affinity
|
|
41
93
|
|
|
42
94
|
Review one affinity surface such as contacts, journals, link queues, commitments, dates, graph state, or merge history.
|
|
43
95
|
|
|
@@ -50,12 +102,16 @@ Read-only.
|
|
|
50
102
|
| Parameter | Type | Required | Values / description |
|
|
51
103
|
| --- | --- | --- | --- |
|
|
52
104
|
| view | string | yes | contacts.list, contacts.duplicates, events.contact_journal, events.link_timeline, events.moments, commitments.open, links.owner, links.observed, links.progression_readiness, links.radar, dates.upcoming, graph.chart, merges.history, merges.dismissed. Which review surface to return. |
|
|
105
|
+
| now | integer / string | no | Optional current timestamp for overdue calculations. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
53
106
|
| contact | object | no | Optional target contact locator. |
|
|
54
107
|
| link | object | no | Optional target link locator. |
|
|
55
108
|
| contactIds | array | no | Optional contact-id subset. |
|
|
56
109
|
| kind | string | no | Optional contact kind or link kind filter, depending on the view. |
|
|
57
110
|
| lifecycleState | string | no | active, dormant, merged, lost. Optional contact lifecycle-state filter. |
|
|
58
111
|
| linkState | string | no | active, dormant, strained, broken, archived. Optional link state filter. |
|
|
112
|
+
| attribute | string / array | no | |
|
|
113
|
+
| tag | string / array | no | |
|
|
114
|
+
| includeLost | boolean | no | Include lost contacts (search excludes them by default). |
|
|
59
115
|
| includeOwner | boolean | no | Whether owner contacts are included. |
|
|
60
116
|
| includeDormant | boolean | no | Whether dormant rows are included. |
|
|
61
117
|
| includeArchived | boolean | no | Whether archived links are included. |
|
|
@@ -68,12 +124,20 @@ Read-only.
|
|
|
68
124
|
| exactOnly | boolean | no | Whether duplicate review is exact-only. |
|
|
69
125
|
| minScore | number | no | Optional duplicate minimum score. |
|
|
70
126
|
| includeDismissed | boolean | no | Whether dismissed pairs are included in duplicate review (marked with dismissed flag). |
|
|
71
|
-
| since | integer | no | Optional lower timestamp bound. |
|
|
72
|
-
| until | integer | no | Optional upper timestamp bound. |
|
|
127
|
+
| since | integer / string | no | Optional lower timestamp bound. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
128
|
+
| until | integer / string | no | Optional upper timestamp bound. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
73
129
|
| limit | integer | no | Optional result limit. |
|
|
74
130
|
| offset | integer | no | Optional result offset. |
|
|
131
|
+
| contact.contactId | integer | no | Exact contact id. |
|
|
132
|
+
| contact.identity | object | no | Contact identity locator. |
|
|
133
|
+
| link.linkId | integer | no | Exact link id. |
|
|
134
|
+
| link.endpoints | object | no | Endpoint-based link locator. |
|
|
75
135
|
|
|
76
|
-
|
|
136
|
+
```sh
|
|
137
|
+
ghostpaw-affinity review events.contact_journal --contact '{"contactId":2}'
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### inspect_affinity_item
|
|
77
141
|
|
|
78
142
|
Inspect one exact affinity item such as the owner profile, a contact profile, or one link detail.
|
|
79
143
|
|
|
@@ -90,10 +154,18 @@ Read-only.
|
|
|
90
154
|
| link | object | no | Target link. Required when kind=link. Provide linkId or endpoints. |
|
|
91
155
|
| topLinksLimit | integer | no | Optional top-links cap. |
|
|
92
156
|
| recentEventsLimit | integer | no | Optional recent-events cap. |
|
|
157
|
+
| contact.contactId | integer | no | Exact contact id. |
|
|
158
|
+
| contact.identity | object | no | Contact identity locator. |
|
|
159
|
+
| link.linkId | integer | no | Exact link id. |
|
|
160
|
+
| link.endpoints | object | no | Endpoint-based link locator. |
|
|
161
|
+
|
|
162
|
+
```sh
|
|
163
|
+
ghostpaw-affinity show contact_profile --contact '{"contactId":2}'
|
|
164
|
+
```
|
|
93
165
|
|
|
94
|
-
|
|
166
|
+
### manage_contact
|
|
95
167
|
|
|
96
|
-
Create a contact
|
|
168
|
+
Create, revise, export or permanently delete a contact (confirm: true required; owner cannot be deleted). Export without contact exports the whole database. Lifecycle lost is soft delete. ALWAYS search_affinity first before creating — duplicates corrupt the graph.
|
|
97
169
|
|
|
98
170
|
Use when: Use this for contact creation and lifecycle-safe contact maintenance.
|
|
99
171
|
|
|
@@ -103,14 +175,28 @@ Writes: writes_state.
|
|
|
103
175
|
|
|
104
176
|
| Parameter | Type | Required | Values / description |
|
|
105
177
|
| --- | --- | --- | --- |
|
|
106
|
-
| action | string | yes | create, revise, set_lifecycle. Operation to perform. |
|
|
178
|
+
| action | string | yes | create, revise, set_lifecycle, export, delete. Operation to perform. |
|
|
107
179
|
| input | object | no | New contact payload. Required when action=create. |
|
|
180
|
+
| confirm | boolean | no | Required true for permanent deletion. |
|
|
108
181
|
| contact | object | no | Target contact. Required when action=revise or set_lifecycle. Provide contactId or identity. |
|
|
109
182
|
| patch | object | no | Allowed contact patch. Required when action=revise. |
|
|
110
183
|
| lifecycleState | string | no | active, dormant, merged, lost. Target lifecycle state. Required when action=set_lifecycle. |
|
|
111
184
|
| options | object | no | Optional lifecycle metadata. |
|
|
112
|
-
|
|
113
|
-
|
|
185
|
+
| input.identities | array | no | Optional identities to attach. Identities already owned by another contact are left with that owner and reported as possible duplicates. |
|
|
186
|
+
| input.name | string | yes | Contact name. |
|
|
187
|
+
| input.kind | string | yes | Contact kind. |
|
|
188
|
+
| input.now | oneOf | no | Optional timestamp. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
189
|
+
| input.bootstrapOwner | boolean | no | Whether this contact should be the owner. |
|
|
190
|
+
| contact.contactId | integer | no | Exact contact id. |
|
|
191
|
+
| contact.identity | object | no | Contact identity locator. |
|
|
192
|
+
| patch.name | string | no | Optional replacement name. |
|
|
193
|
+
| options.now | oneOf | no | Optional timestamp. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
194
|
+
|
|
195
|
+
```sh
|
|
196
|
+
ghostpaw-affinity contact create '{"name":"Fox","kind":"human","bootstrapOwner":true}'
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### merge_contacts
|
|
114
200
|
|
|
115
201
|
Merge one loser contact into one winner contact using explicit contact locators.
|
|
116
202
|
|
|
@@ -125,11 +211,19 @@ Writes: writes_state.
|
|
|
125
211
|
| winner | object | yes | Winner contact. Provide contactId or identity. |
|
|
126
212
|
| loser | object | yes | Loser contact. Provide contactId or identity. |
|
|
127
213
|
| reasonSummary | string | no | Optional merge reason. |
|
|
128
|
-
| now | integer | no | Optional merge timestamp. |
|
|
214
|
+
| now | integer / string | no | Optional merge timestamp. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
215
|
+
| winner.contactId | integer | no | Exact contact id. |
|
|
216
|
+
| winner.identity | object | no | Contact identity locator. |
|
|
217
|
+
| loser.contactId | integer | no | Exact contact id. |
|
|
218
|
+
| loser.identity | object | no | Contact identity locator. |
|
|
219
|
+
|
|
220
|
+
```sh
|
|
221
|
+
ghostpaw-affinity contact merge --winner '{"contactId":2}' --loser '{"contactId":8}' --reason-summary "same person"
|
|
222
|
+
```
|
|
129
223
|
|
|
130
|
-
|
|
224
|
+
### manage_duplicate_dismissal
|
|
131
225
|
|
|
132
|
-
Dismiss or un-dismiss a duplicate candidate pair so it does not resurface in
|
|
226
|
+
Dismiss or un-dismiss a duplicate candidate pair so it does not resurface in review_affinity contacts.duplicates.
|
|
133
227
|
|
|
134
228
|
Use when: Use dismiss after confirming two contacts are different people (not duplicates). Use undismiss to re-surface a pair for re-evaluation.
|
|
135
229
|
|
|
@@ -143,8 +237,16 @@ Writes: writes_state.
|
|
|
143
237
|
| left | object | yes | Left contact. Provide contactId or identity. |
|
|
144
238
|
| right | object | yes | Right contact. Provide contactId or identity. |
|
|
145
239
|
| reason | any | no | Optional reason for the dismissal. |
|
|
240
|
+
| left.contactId | integer | no | Exact contact id. |
|
|
241
|
+
| left.identity | object | no | Contact identity locator. |
|
|
242
|
+
| right.contactId | integer | no | Exact contact id. |
|
|
243
|
+
| right.identity | object | no | Contact identity locator. |
|
|
146
244
|
|
|
147
|
-
|
|
245
|
+
```sh
|
|
246
|
+
ghostpaw-affinity duplicate dismiss --left '{"contactId":5}' --right '{"contactId":10}' --reason '"different people"'
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### manage_identity
|
|
148
250
|
|
|
149
251
|
Add, revise, verify, or remove one routing identity on a contact. Use this for emails, phone numbers, social handles, and URLs — anything that could locate a person. Do not use manage_attribute for these.
|
|
150
252
|
|
|
@@ -161,10 +263,24 @@ Writes: writes_state.
|
|
|
161
263
|
| input | object | no | New identity payload. Required when action=add. |
|
|
162
264
|
| identityId | integer | no | Identity id. Required when action=revise, verify, or remove. |
|
|
163
265
|
| patch | object | no | Identity patch. Required when action=revise. |
|
|
164
|
-
| verifiedAt | integer | no | Verification timestamp. Optional for action=verify. |
|
|
165
|
-
| removedAt | integer | no | Removal timestamp. Optional for action=remove. |
|
|
166
|
-
|
|
167
|
-
|
|
266
|
+
| verifiedAt | integer / string | no | Verification timestamp. Optional for action=verify. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
267
|
+
| removedAt | integer / string | no | Removal timestamp. Optional for action=remove. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
268
|
+
| contact.contactId | integer | no | Exact contact id. |
|
|
269
|
+
| contact.identity | object | no | Contact identity locator. |
|
|
270
|
+
| input.type | string | yes | Identity type: email, phone, url, website, handle, x, twitter, linkedin, github, mastodon, bluesky, telegram, whatsapp, signal, matrix, discord, slack, instagram, facebook, youtube, tiktok, address, other, account_id, alias, or custom:<name> (lowercase a-z, 0-9, underscore or hyphen). |
|
|
271
|
+
| input.value | string | yes | Identity value. |
|
|
272
|
+
| input.label | string | no | Optional label. |
|
|
273
|
+
| input.verified | boolean | no | Whether the identity starts verified. |
|
|
274
|
+
| input.now | oneOf | no | Optional timestamp. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
275
|
+
| patch.type | string | no | Optional identity type: email, phone, url, website, handle, x, twitter, linkedin, github, mastodon, bluesky, telegram, whatsapp, signal, matrix, discord, slack, instagram, facebook, youtube, tiktok, address, other, account_id, alias, or custom:<name> (lowercase a-z, 0-9, underscore or hyphen). |
|
|
276
|
+
| patch.value | string | no | Optional identity value. |
|
|
277
|
+
| patch.label | string | no | Optional label. |
|
|
278
|
+
|
|
279
|
+
```sh
|
|
280
|
+
ghostpaw-affinity identity add --contact '{"contactId":2}' --input '{"type":"email","value":"jana@x.de"}'
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### manage_relationship
|
|
168
284
|
|
|
169
285
|
Seed social links, revise bond and state, and manage structural ties. Seed a link as soon as a relationship is mentioned — do not wait for repeated evidence.
|
|
170
286
|
|
|
@@ -186,9 +302,20 @@ Writes: writes_state.
|
|
|
186
302
|
| bond | any | no | Bond text. Required when action=revise_bond. Null to clear. |
|
|
187
303
|
| state | string | no | active, dormant, strained, broken, archived. Link state. Required when action=override_state. |
|
|
188
304
|
| options | object | no | Optional metadata. |
|
|
189
|
-
| removedAt | integer | no | Removal timestamp. Optional for action=remove_structural_tie. |
|
|
305
|
+
| removedAt | integer / string | no | Removal timestamp. Optional for action=remove_structural_tie. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
306
|
+
| from.contactId | integer | no | Exact contact id. |
|
|
307
|
+
| from.identity | object | no | Contact identity locator. |
|
|
308
|
+
| to.contactId | integer | no | Exact contact id. |
|
|
309
|
+
| to.identity | object | no | Contact identity locator. |
|
|
310
|
+
| link.linkId | integer | no | Exact link id. |
|
|
311
|
+
| link.endpoints | object | no | Endpoint-based link locator. |
|
|
312
|
+
| options.now | oneOf | no | Optional timestamp. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
190
313
|
|
|
191
|
-
|
|
314
|
+
```sh
|
|
315
|
+
ghostpaw-affinity relationship tie --from '{"contactId":2}' --to '{"contactId":3}' --kind works_at --role Founder
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### record_event
|
|
192
319
|
|
|
193
320
|
Record one social event such as an interaction, observation, milestone, or transaction. For interactions, milestones, and transactions the owner contact is auto-injected into participants if missing. Observations may omit the owner when recording third-party evidence.
|
|
194
321
|
|
|
@@ -202,8 +329,18 @@ Writes: writes_state.
|
|
|
202
329
|
| --- | --- | --- | --- |
|
|
203
330
|
| kind | string | yes | interaction, observation, milestone, transaction. Event kind. |
|
|
204
331
|
| input | object | yes | Event payload. Always required. Interaction events also require `type`. |
|
|
332
|
+
| input.type | string | no | Interaction subtype. Required when kind=interaction, omit otherwise. |
|
|
333
|
+
| input.occurredAt | oneOf | yes | When the event occurred, Unix timestamp in milliseconds. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
334
|
+
| input.summary | string | yes | Event summary. Must be non-empty. |
|
|
335
|
+
| input.significance | integer | yes | Event significance from 1 to 10. |
|
|
336
|
+
| input.participants | array | yes | Participant list. Must be non-empty and include the owner contact. |
|
|
337
|
+
| input.now | oneOf | no | Optional timestamp override. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
338
|
+
|
|
339
|
+
```sh
|
|
340
|
+
ghostpaw-affinity event record --kind interaction --input '{"type":"conversation","occurredAt":"today","summary":"Call re pilot","significance":6,"participants":[{"contactId":2,"role":"recipient","directionality":"mutual"}]}'
|
|
341
|
+
```
|
|
205
342
|
|
|
206
|
-
|
|
343
|
+
### manage_commitment
|
|
207
344
|
|
|
208
345
|
Record or resolve one commitment such as a promise or agreement. The owner contact is auto-injected into participants if missing.
|
|
209
346
|
|
|
@@ -220,8 +357,21 @@ Writes: writes_state.
|
|
|
220
357
|
| commitmentEventId | integer | no | Commitment event id. Required when action=resolve. |
|
|
221
358
|
| resolution | string | no | kept, cancelled, broken. How the commitment was resolved. Required when action=resolve. |
|
|
222
359
|
| options | object | no | Optional metadata. |
|
|
223
|
-
|
|
224
|
-
|
|
360
|
+
| input.commitmentType | string | yes | Promise or agreement. |
|
|
361
|
+
| input.occurredAt | oneOf | yes | When the commitment was made, Unix timestamp in milliseconds. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
362
|
+
| input.summary | string | yes | Commitment summary. Must be non-empty. |
|
|
363
|
+
| input.significance | integer | yes | Commitment significance from 1 to 10. |
|
|
364
|
+
| input.dueAt | oneOf | no | Optional due timestamp. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
365
|
+
| input.participants | array | yes | Participant list. Must be non-empty and include the owner contact. |
|
|
366
|
+
| input.now | oneOf | no | Optional timestamp override. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
367
|
+
| options.now | oneOf | no | Optional timestamp. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
368
|
+
| options.resolvingEvent | object | no | |
|
|
369
|
+
|
|
370
|
+
```sh
|
|
371
|
+
ghostpaw-affinity commitment record --input '{"commitmentType":"promise","occurredAt":"today","dueAt":"+3d","summary":"Send proposal","significance":6,"participants":[{"contactId":2,"role":"recipient"}]}'
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### manage_date_anchor
|
|
225
375
|
|
|
226
376
|
Add, revise, or remove recurring date anchors on contacts or links. Use this for birthdays, anniversaries, and yearly events — not manage_attribute.
|
|
227
377
|
|
|
@@ -238,9 +388,28 @@ Writes: writes_state.
|
|
|
238
388
|
| anchorEventId | integer | no | Anchor event id. Required when action=revise or remove. |
|
|
239
389
|
| patch | object | no | Anchor patch. Required when action=revise. |
|
|
240
390
|
| options | object | no | Optional metadata. |
|
|
241
|
-
| removedAt | integer | no | Removal timestamp. Optional for action=remove. |
|
|
242
|
-
|
|
243
|
-
|
|
391
|
+
| removedAt | integer / string | no | Removal timestamp. Optional for action=remove. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
392
|
+
| input.target | object | yes | Date-anchor target. |
|
|
393
|
+
| input.recurrenceKind | string | yes | Recurrence kind. |
|
|
394
|
+
| input.anchorMonth | integer | yes | Anchor month, 1–12. |
|
|
395
|
+
| input.anchorDay | integer | yes | Anchor day, 1–31 (validated per month). |
|
|
396
|
+
| input.summary | string | yes | Summary. Must be non-empty. |
|
|
397
|
+
| input.significance | integer | yes | Significance from 1 to 10. |
|
|
398
|
+
| input.now | oneOf | no | Optional timestamp override. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
399
|
+
| input.force | boolean | no | Whether to bypass duplicate checks. |
|
|
400
|
+
| patch.recurrenceKind | string | no | Optional recurrence kind. |
|
|
401
|
+
| patch.anchorMonth | integer | no | Optional month, 1–12. |
|
|
402
|
+
| patch.anchorDay | integer | no | Optional day, 1–31. |
|
|
403
|
+
| patch.summary | string | no | Optional summary. |
|
|
404
|
+
| patch.significance | integer | no | Optional significance, 1–10. |
|
|
405
|
+
| options.now | oneOf | no | Optional timestamp. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
406
|
+
| options.force | boolean | no | Whether duplicate checks should be bypassed. |
|
|
407
|
+
|
|
408
|
+
```sh
|
|
409
|
+
ghostpaw-affinity date add --input '{"target":{"kind":"contact","contact":{"contactId":2}},"recurrenceKind":"birthday","anchorMonth":11,"anchorDay":3,"summary":"Jana bday","significance":4}'
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### manage_attribute
|
|
244
413
|
|
|
245
414
|
Set, unset, or replace custom metadata attributes on contacts and links. For emails, phones, handles, and URLs use manage_identity instead — those are routing keys, not attributes.
|
|
246
415
|
|
|
@@ -257,9 +426,18 @@ Writes: writes_state.
|
|
|
257
426
|
| name | string | no | Attribute name. Required when action=set or unset. |
|
|
258
427
|
| value | any | no | Attribute value. Required when action=set. Null for presence/tag semantics. |
|
|
259
428
|
| entries | array | no | Key-value map to replace all attributes. Required when action=replace. |
|
|
260
|
-
| removedAt | integer | no | Removal timestamp. Optional for action=unset. |
|
|
429
|
+
| removedAt | integer / string | no | Removal timestamp. Optional for action=unset. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
|
|
430
|
+
| target.kind | string | yes | Target kind. |
|
|
431
|
+
| target.contact | object | no | Contact locator. Required when kind=contact. Provide contactId or identity. |
|
|
432
|
+
| target.link | object | no | Link locator. Required when kind=link. Provide linkId or endpoints. |
|
|
433
|
+
| entries.name | string | yes | Attribute name. |
|
|
434
|
+
| entries.value | oneOf | no | Attribute value, or null for presence/tag semantics. |
|
|
261
435
|
|
|
262
|
-
|
|
436
|
+
```sh
|
|
437
|
+
ghostpaw-affinity attribute set --target '{"kind":"contact","contact":{"contactId":2}}' --name pipeline_stage --value '"proposal"'
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### Workflow guides
|
|
263
441
|
|
|
264
442
|
- [bootstrap-and-cold-start](skills/affinity/references/bootstrap-and-cold-start.md): Establish a clean Affinity baseline with one owner, one verified identity, and the minimum structure needed for later evidence and review work.
|
|
265
443
|
- [identify-and-locate-contacts](skills/affinity/references/identify-and-locate-contacts.md): Find the right contact reliably, prefer stable natural keys when possible, and avoid creating duplicates through weak lookup discipline.
|
|
@@ -273,7 +451,7 @@ Writes: writes_state.
|
|
|
273
451
|
- [review-radar-progression-and-graph](skills/affinity/references/review-radar-progression-and-graph.md): Use the review surfaces to prioritize maintenance, understand progression readiness, and read the shape of the relationship graph without guessing from raw rows.
|
|
274
452
|
- [reconcile-duplicates-and-merge-safely](skills/affinity/references/reconcile-duplicates-and-merge-safely.md): Review duplicate candidates carefully and merge only after the identity, history, and structural consequences are understood.
|
|
275
453
|
|
|
276
|
-
|
|
454
|
+
### Principles
|
|
277
455
|
|
|
278
456
|
- Honor evidence before narrative.
|
|
279
457
|
- Clarify before you act.
|
|
@@ -281,3 +459,9 @@ Writes: writes_state.
|
|
|
281
459
|
- Read derived signals with judgment.
|
|
282
460
|
- Protect relationship integrity over time.
|
|
283
461
|
- Follow the operational protocol.
|
|
462
|
+
|
|
463
|
+
From the binary: `ghostpaw-affinity skill <guide>`.
|
|
464
|
+
|
|
465
|
+
## Without the binary
|
|
466
|
+
|
|
467
|
+
Use `npx -y @ghostpaw/affinity ...` (Node.js 24 or newer), or import `@ghostpaw/affinity` as a library.
|