@ghostpaw/affinity 0.1.3

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) GhostPaw
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,250 @@
1
+ # @ghostpaw/affinity
2
+
3
+ [![npm](https://img.shields.io/npm/v/@ghostpaw/affinity)](https://www.npmjs.com/package/@ghostpaw/affinity)
4
+ [![node](https://img.shields.io/node/v/@ghostpaw/affinity)](https://nodejs.org)
5
+ [![license](https://img.shields.io/npm/l/@ghostpaw/affinity)](LICENSE)
6
+ [![dependencies](https://img.shields.io/badge/dependencies-0-brightgreen)](package.json)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.8-blue?logo=typescript&logoColor=white)](https://www.typescriptlang.org)
8
+
9
+ A standalone social CRM core for Node.js, built on SQLite.
10
+
11
+ Affinity treats contacts, identities, relationship mechanics, structural ties,
12
+ journal evidence, commitments, recurring dates, attributes, and graph review as
13
+ one coherent model instead of separate systems. It ships as a single prebundled
14
+ blob with zero runtime dependencies, designed for two audiences at once: human
15
+ developers working directly in code, and LLM agents operating through a
16
+ structured `soul` / `tools` / `skills` runtime.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ npm install @ghostpaw/affinity
22
+ ```
23
+
24
+ Requires **Node.js 24+** (uses the built-in `node:sqlite` module).
25
+
26
+ ## Quick Start
27
+
28
+ ```ts
29
+ import { DatabaseSync } from "node:sqlite";
30
+ import { initAffinityTables, read, write } from "@ghostpaw/affinity";
31
+
32
+ const db = new DatabaseSync(":memory:");
33
+ db.exec("PRAGMA foreign_keys = ON");
34
+ initAffinityTables(db);
35
+
36
+ const { primary: owner } = write.createContact(db, {
37
+ name: "Mika",
38
+ kind: "human",
39
+ bootstrapOwner: true,
40
+ });
41
+
42
+ const { primary: ada } = write.createContact(db, {
43
+ name: "Ada Lovelace",
44
+ kind: "human",
45
+ });
46
+
47
+ write.addIdentity(db, ada.id, {
48
+ type: "email",
49
+ value: "ada@example.com",
50
+ });
51
+
52
+ write.recordInteraction(db, {
53
+ type: "conversation",
54
+ occurredAt: Date.now(),
55
+ summary: "Coffee together",
56
+ significance: 6,
57
+ participants: [
58
+ { contactId: owner.id, role: "actor", directionality: "mutual" },
59
+ { contactId: ada.id, role: "recipient", directionality: "mutual" },
60
+ ],
61
+ });
62
+
63
+ const profile = read.getContactProfile(db, ada.id);
64
+ const radar = read.listRadar(db);
65
+ ```
66
+
67
+ ## The Model
68
+
69
+ Eight concepts, strict separation of concerns:
70
+
71
+ | Concept | Purpose |
72
+ |---|---|
73
+ | **Contact** | Any tracked entity: person, company, team, service, pet, household, or group |
74
+ | **Identity** | Exact recognition and routing handle such as email, phone, URL, or account id |
75
+ | **Social Link** | A live relationship track with Rank, Affinity, Trust, cadence, Bond, and state |
76
+ | **Tie** | A structural fact such as `works_at`, `belongs_to`, `reports_to`, or kinship |
77
+ | **Journal Entry** | Recorded evidence: interaction, observation, milestone, transaction, or commitment |
78
+ | **Date Anchor** | A recurring yearly date such as a birthday, anniversary, renewal, or memorial |
79
+ | **Attribute** | Flexible metadata and preference layer for contacts and links |
80
+ | **Affinity Chart** | Derived graph view of the active relationship network |
81
+
82
+ The model means each kind of truth has its own home:
83
+
84
+ | What it looks like | What it actually is |
85
+ |---|---|
86
+ | A person, company, team, service, or household | A Contact |
87
+ | An email address or handle | An Identity |
88
+ | A friendship or business relationship that changes over time | A Social Link |
89
+ | Employment, hierarchy, family, or membership | A Tie |
90
+ | “We talked yesterday” | A Journal entry |
91
+ | “I promised to send the recap” | A commitment-shaped Journal entry |
92
+ | “Their birthday is important every year” | A Date Anchor |
93
+
94
+ State is derived, not hand-toggled. Rank, hidden Affinity, Trust movement,
95
+ Moments, drift, readiness, and graph bridge significance are computed from
96
+ evidence and explicit structural truth, not caller-written status flags.
97
+
98
+ ## Two Audiences
99
+
100
+ ### Human developers
101
+
102
+ Use the `read` and `write` namespaces for direct-code access to the domain:
103
+
104
+ ```ts
105
+ import { read, write } from "@ghostpaw/affinity";
106
+
107
+ write.createContact(db, { name: "Ada", kind: "human" });
108
+ write.addIdentity(db, contactId, { type: "email", value: "ada@example.com" });
109
+ write.recordInteraction(db, {
110
+ type: "support",
111
+ occurredAt: now,
112
+ summary: "Helped prepare for a difficult meeting",
113
+ significance: 7,
114
+ participants: [
115
+ { contactId: ownerId, role: "actor", directionality: "mutual" },
116
+ { contactId, role: "recipient", directionality: "mutual" },
117
+ ],
118
+ });
119
+
120
+ const profile = read.getContactProfile(db, contactId);
121
+ const radar = read.listRadar(db);
122
+ ```
123
+
124
+ See [HUMAN.md](docs/HUMAN.md) for the full direct-code guide with modeling
125
+ boundaries and worked examples.
126
+
127
+ ### LLM agents
128
+
129
+ Use the `tools`, `skills`, and `soul` namespaces for a structured runtime
130
+ surface designed to minimize LLM cognitive load:
131
+
132
+ ```ts
133
+ import { tools, skills, soul } from "@ghostpaw/affinity";
134
+
135
+ const allTools = tools.affinityTools;
136
+ const searchTool = tools.getAffinityToolByName("search_affinity")!;
137
+ const result = searchTool.handler(db, { query: "email:ada@example.com" });
138
+
139
+ const allSkills = skills.affinitySkills;
140
+ const prompt = soul.renderAffinitySoulPromptFoundation();
141
+ ```
142
+
143
+ Every tool returns a discriminated result with `outcome: "success" | "no_op" |
144
+ "needs_clarification" | "error"`, structured entities, next-step hints, and
145
+ actionable recovery signals.
146
+
147
+ See [LLM.md](docs/LLM.md) for the full AI-facing guide covering soul, tools,
148
+ and skills.
149
+
150
+ ## Tools
151
+
152
+ Eleven tools shaped around operator intent, not raw storage operations:
153
+
154
+ | Tool | What it does |
155
+ |---|---|
156
+ | `search_affinity` | Search contacts by natural key or name |
157
+ | `review_affinity` | Dashboard-style list and graph review views |
158
+ | `inspect_affinity_item` | Open one exact profile or link detail |
159
+ | `manage_contact` | Create, revise, or change contact lifecycle |
160
+ | `merge_contacts` | Merge duplicate contacts safely |
161
+ | `manage_identity` | Add, revise, verify, or remove identities |
162
+ | `manage_relationship` | Seed social links, revise bond/state, manage structural ties |
163
+ | `record_event` | Record direct evidence, observations, milestones, or transactions |
164
+ | `manage_commitment` | Record or resolve obligations |
165
+ | `manage_date_anchor` | Add, revise, or remove recurring important dates |
166
+ | `manage_attribute` | Set, unset, or replace contact/link metadata |
167
+
168
+ Each tool exports runtime metadata, JSON-Schema-compatible inputs, and
169
+ structured outputs so harnesses can wire them without parsing vague prose.
170
+
171
+ ## Key Properties
172
+
173
+ - **Zero runtime dependencies.** Only `node:sqlite` (built into Node 24+).
174
+ - **Single prebundled blob.** One ESM + one CJS entry in `dist/`. No subpath
175
+ exports, no code splitting.
176
+ - **Pure SQLite storage.** CHECK-constrained state, trigger-maintained support
177
+ tables, and deterministic derived reads. Bring your own `DatabaseSync`.
178
+ - **Derived mechanics.** Rank, hidden Affinity, Trust, cadence, Moments, Radar,
179
+ and bridge significance are computed from evidence and structure, never
180
+ directly caller-set.
181
+ - **Intention-shaped writes.** `createContact`, `setStructuralTie`,
182
+ `recordInteraction`, `recordCommitment`, `addDateAnchor`, `mergeContacts`:
183
+ operations that say what happened or what truth changed, not generic CRUD.
184
+ - **Additive AI runtime.** `soul` for posture, `tools` for actions, `skills` for
185
+ workflow guidance.
186
+ - **Colocated tests.** Every non-type module has a colocated `.test.ts` file.
187
+ The documented behavior is backed by executable coverage.
188
+
189
+ ## Package Surface
190
+
191
+ ```ts
192
+ import {
193
+ initAffinityTables, // schema setup
194
+ read, // all query functions
195
+ write, // all mutation functions
196
+ tools, // LLM tool definitions + registry
197
+ skills, // LLM workflow skills + registry
198
+ soul, // thinking foundation for system prompts
199
+ } from "@ghostpaw/affinity";
200
+ ```
201
+
202
+ All domain and runtime types are also available at the root for TypeScript
203
+ consumers:
204
+
205
+ ```ts
206
+ import type {
207
+ AffinityDb,
208
+ ContactKind,
209
+ LinkState,
210
+ ContactProfileRecord,
211
+ AffinityChartRecord,
212
+ AffinityToolDefinition,
213
+ AffinitySkill,
214
+ AffinitySoul,
215
+ } from "@ghostpaw/affinity";
216
+ ```
217
+
218
+ ## Documentation
219
+
220
+ | Document | Audience |
221
+ |---|---|
222
+ | [HUMAN.md](docs/HUMAN.md) | Human developers using the low-level `read` / `write` API |
223
+ | [LLM.md](docs/LLM.md) | Agent builders wiring `soul`, `tools`, and `skills` into LLM systems |
224
+ | [docs/README.md](docs/README.md) | Architecture overview: model, invariants, mechanics, and source layout |
225
+ | [docs/entities/](docs/entities/) | Per-concept manuals with exact inlined public API listings |
226
+ | [docs/USECASES.md](docs/USECASES.md) | Long-form lifecycle narratives across personal, business, and AI-memory angles |
227
+
228
+ ## Development
229
+
230
+ ```bash
231
+ npm install
232
+ npm test # node:test runner
233
+ npm run typecheck # tsc --noEmit
234
+ npm run lint # biome check
235
+ npm run build # ESM + CJS + declarations via tsup
236
+ ```
237
+
238
+ The repo is pinned to **Node 24.14.0** via `.nvmrc` / `.node-version` /
239
+ `.tool-versions` / `mise.toml` / Volta. Use whichever version manager you
240
+ prefer.
241
+
242
+ ### Support
243
+
244
+ If this package helps your project, consider sponsoring its maintenance:
245
+
246
+ [![GitHub Sponsors](https://img.shields.io/badge/Sponsor-EA4AAA?style=for-the-badge&logo=github&logoColor=white)](https://github.com/sponsors/Anonyfox)
247
+
248
+ ---
249
+
250
+ **[Anonyfox](https://anonyfox.com) • [MIT License](LICENSE)**