@ghostpaw/affinity 0.4.1 → 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 +171 -114
- package/SKILL.md +217 -33
- package/dist/cli.js +2433 -913
- package/dist/index.cjs +1397 -504
- package/dist/index.d.cts +556 -55
- package/dist/index.d.ts +556 -55
- package/dist/index.js +1397 -504
- package/dist/mcp-server.js +1811 -694
- package/dist/mcp.cjs +1604 -606
- package/dist/mcp.js +1605 -607
- package/package.json +1 -1
- package/skills/affinity/SKILL.md +217 -33
package/README.md
CHANGED
|
@@ -6,117 +6,101 @@
|
|
|
6
6
|
|
|
7
7
|
**Agent contacts: people, promises and yearly dates, with a radar for who is drifting.**
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
A local social CRM: contacts, identities, relationships, journal events,
|
|
10
|
+
commitments and recurring dates in one SQLite file. One self-contained binary
|
|
11
|
+
per platform, an MCP server, and a zero-dependency TypeScript library.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## Install
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
one coherent model instead of separate systems. It ships as a single prebundled
|
|
18
|
-
blob with zero runtime dependencies, designed for two audiences at once: human
|
|
19
|
-
developers working directly in code, and LLM agents operating through a
|
|
20
|
-
structured `soul` / `tools` / `skills` runtime.
|
|
15
|
+
Each line downloads the latest release for one platform, checks it against
|
|
16
|
+
`SHA256SUMS`, puts `ghostpaw-affinity` on your `PATH` and prints the version.
|
|
21
17
|
|
|
22
|
-
|
|
18
|
+
**Linux x64**
|
|
23
19
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
```sh
|
|
21
|
+
cd "$(mktemp -d)" && T=linux-x64 && V=$(curl -fsSLI -o /dev/null -w '%{url_effective}' https://github.com/GhostPawJS/affinity/releases/latest | sed 's|.*/v||') && F=ghostpaw-affinity-$V-$T.tar.gz && U=https://github.com/GhostPawJS/affinity/releases/download/v$V && curl -fsSL -O "$U/$F" -O "$U/SHA256SUMS" && grep " $F\$" SHA256SUMS | sha256sum -c - && tar -xzf "$F" ghostpaw-affinity && mkdir -p ~/.local/bin && mv ghostpaw-affinity ~/.local/bin/ && { case ":$PATH:" in *":$HOME/.local/bin:"*) ;; *) echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.profile; export PATH="$HOME/.local/bin:$PATH";; esac; } && ghostpaw-affinity --version
|
|
22
|
+
```
|
|
27
23
|
|
|
28
|
-
**
|
|
24
|
+
**Linux arm64**
|
|
29
25
|
|
|
30
|
-
```
|
|
31
|
-
|
|
26
|
+
```sh
|
|
27
|
+
cd "$(mktemp -d)" && T=linux-arm64 && V=$(curl -fsSLI -o /dev/null -w '%{url_effective}' https://github.com/GhostPawJS/affinity/releases/latest | sed 's|.*/v||') && F=ghostpaw-affinity-$V-$T.tar.gz && U=https://github.com/GhostPawJS/affinity/releases/download/v$V && curl -fsSL -O "$U/$F" -O "$U/SHA256SUMS" && grep " $F\$" SHA256SUMS | sha256sum -c - && tar -xzf "$F" ghostpaw-affinity && mkdir -p ~/.local/bin && mv ghostpaw-affinity ~/.local/bin/ && { case ":$PATH:" in *":$HOME/.local/bin:"*) ;; *) echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.profile; export PATH="$HOME/.local/bin:$PATH";; esac; } && ghostpaw-affinity --version
|
|
32
28
|
```
|
|
33
29
|
|
|
34
|
-
|
|
30
|
+
**macOS Apple silicon**
|
|
35
31
|
|
|
36
|
-
```
|
|
37
|
-
/
|
|
38
|
-
/plugin install ghostpaw-affinity@ghostpaw-affinity
|
|
32
|
+
```sh
|
|
33
|
+
cd "$(mktemp -d)" && T=darwin-arm64 && V=$(curl -fsSLI -o /dev/null -w '%{url_effective}' https://github.com/GhostPawJS/affinity/releases/latest | sed 's|.*/v||') && F=ghostpaw-affinity-$V-$T.tar.gz && U=https://github.com/GhostPawJS/affinity/releases/download/v$V && curl -fsSL -O "$U/$F" -O "$U/SHA256SUMS" && grep " $F\$" SHA256SUMS | shasum -a 256 -c - && tar -xzf "$F" ghostpaw-affinity && sudo mkdir -p /usr/local/bin && sudo mv ghostpaw-affinity /usr/local/bin/ && ghostpaw-affinity --version
|
|
39
34
|
```
|
|
40
35
|
|
|
41
|
-
**
|
|
36
|
+
**macOS Intel**
|
|
42
37
|
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
command = "npx"
|
|
46
|
-
args = ["-y", "@ghostpaw/affinity", "mcp"]
|
|
38
|
+
```sh
|
|
39
|
+
cd "$(mktemp -d)" && T=darwin-x64 && V=$(curl -fsSLI -o /dev/null -w '%{url_effective}' https://github.com/GhostPawJS/affinity/releases/latest | sed 's|.*/v||') && F=ghostpaw-affinity-$V-$T.tar.gz && U=https://github.com/GhostPawJS/affinity/releases/download/v$V && curl -fsSL -O "$U/$F" -O "$U/SHA256SUMS" && grep " $F\$" SHA256SUMS | shasum -a 256 -c - && tar -xzf "$F" ghostpaw-affinity && sudo mkdir -p /usr/local/bin && sudo mv ghostpaw-affinity /usr/local/bin/ && ghostpaw-affinity --version
|
|
47
40
|
```
|
|
48
41
|
|
|
49
|
-
**
|
|
50
|
-
or a project `.mcp.json`:
|
|
42
|
+
**Windows x64 (PowerShell)**
|
|
51
43
|
|
|
52
|
-
```
|
|
53
|
-
{
|
|
54
|
-
"mcpServers": {
|
|
55
|
-
"ghostpaw-affinity": {
|
|
56
|
-
"command": "npx",
|
|
57
|
-
"args": ["-y", "@ghostpaw/affinity", "mcp"]
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
44
|
+
```powershell
|
|
45
|
+
$r='GhostPawJS/affinity'; $v=(irm "https://api.github.com/repos/$r/releases/latest").tag_name; $f="ghostpaw-affinity-$($v.TrimStart('v'))-windows-x64.zip"; $u="https://github.com/$r/releases/download/$v"; $t=(New-Item -ItemType Directory (Join-Path $env:TEMP ([guid]::NewGuid()))).FullName; iwr "$u/$f" -OutFile "$t\$f" -UseBasicParsing; iwr "$u/SHA256SUMS" -OutFile "$t\SHA256SUMS" -UseBasicParsing; $want=((Get-Content "$t\SHA256SUMS" | Where-Object { $_ -like "* $f" }) -split '\s+')[0]; if (-not $want -or (Get-FileHash "$t\$f" -Algorithm SHA256).Hash -ne $want) { throw "checksum mismatch for $f" }; $d=Join-Path $env:LOCALAPPDATA 'Programs\ghostpaw\bin'; Expand-Archive "$t\$f" $t -Force; New-Item -ItemType Directory -Force $d | Out-Null; Copy-Item "$t\ghostpaw-affinity.exe" $d -Force; $p=[Environment]::GetEnvironmentVariable('Path','User'); if (";$p;" -notlike "*;$d;*") { [Environment]::SetEnvironmentVariable('Path',"$p;$d",'User') }; $env:Path="$d;$env:Path"; ghostpaw-affinity --version
|
|
61
46
|
```
|
|
62
47
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
`docker build -t ghostpaw-affinity . && docker run -i --rm -v affinity:/data ghostpaw-affinity`.
|
|
48
|
+
Linux installs to `~/.local/bin` (added to `~/.profile` if missing), macOS to
|
|
49
|
+
`/usr/local/bin` (asks for sudo), Windows to `%LOCALAPPDATA%\Programs\ghostpaw\bin`
|
|
50
|
+
(added to the user `PATH`; open a new terminal afterwards).
|
|
67
51
|
|
|
68
|
-
|
|
69
|
-
initialize-based revisions 2025-11-25, 2025-06-18, 2025-03-26 and 2024-11-05.
|
|
70
|
-
|
|
71
|
-
### CLI
|
|
52
|
+
Then:
|
|
72
53
|
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
54
|
+
```sh
|
|
55
|
+
ghostpaw-affinity contact create '{"name":"Sam","kind":"human"}'
|
|
56
|
+
ghostpaw-affinity search sam
|
|
57
|
+
ghostpaw-affinity skill # cheat sheet and tool reference
|
|
77
58
|
```
|
|
78
59
|
|
|
79
|
-
|
|
80
|
-
`
|
|
60
|
+
Contacts live in `~/.ghostpaw/affinity.db` unless `--db <path>` or the
|
|
61
|
+
`GHOSTPAW_AFFINITY_DB` environment variable says otherwise; relative paths
|
|
62
|
+
resolve against the current directory.
|
|
81
63
|
|
|
82
|
-
|
|
64
|
+
A session with the linux-x64 binary against a fresh database:
|
|
83
65
|
|
|
84
|
-
|
|
85
|
-
[Agent Skills](https://agentskills.io) format and ship in the npm package.
|
|
86
|
-
Copy `skills/affinity/` into your agent's skills folder, or print it:
|
|
87
|
-
|
|
88
|
-
```bash
|
|
89
|
-
npx -y @ghostpaw/affinity skill > SKILL.md
|
|
90
|
-
```
|
|
66
|
+

|
|
91
67
|
|
|
92
|
-
|
|
68
|
+
The same session as an [animated GIF](https://raw.githubusercontent.com/GhostPawJS/affinity/main/docs/assets/cli.gif).
|
|
93
69
|
|
|
70
|
+
### npx / npm (for npm-based environments)
|
|
94
71
|
|
|
95
|
-
The [npm package](https://www.npmjs.com/package/@ghostpaw/affinity)
|
|
72
|
+
The [npm package](https://www.npmjs.com/package/@ghostpaw/affinity) needs Node 24+
|
|
73
|
+
and has zero runtime dependencies:
|
|
96
74
|
|
|
97
75
|
```sh
|
|
98
|
-
npm install -g @ghostpaw/affinity
|
|
99
76
|
npx -y @ghostpaw/affinity --help
|
|
77
|
+
npm install -g @ghostpaw/affinity # provides ghostpaw-affinity
|
|
100
78
|
```
|
|
101
79
|
|
|
102
|
-
|
|
103
|
-
for linux-x64, linux-arm64, darwin-arm64, darwin-x64 and windows-x64.
|
|
80
|
+
### Library (for harnesses)
|
|
104
81
|
|
|
105
82
|
```sh
|
|
106
|
-
|
|
83
|
+
npm install @ghostpaw/affinity
|
|
107
84
|
```
|
|
108
85
|
|
|
109
|
-
```
|
|
110
|
-
|
|
86
|
+
```ts
|
|
87
|
+
import { DatabaseSync } from "node:sqlite";
|
|
88
|
+
import { initAffinityTables, read, write, tools } from "@ghostpaw/affinity";
|
|
111
89
|
```
|
|
112
90
|
|
|
113
|
-
|
|
91
|
+
See [Quick Start](#quick-start) and [docs/LLM.md](docs/LLM.md) for the tool facade.
|
|
114
92
|
|
|
115
|
-
|
|
93
|
+
### Other installers and verification
|
|
116
94
|
|
|
117
|
-
|
|
95
|
+
Interactive installers (also verify `SHA256SUMS`):
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
curl -fsSL https://raw.githubusercontent.com/GhostPawJS/affinity/main/install.sh | sh
|
|
99
|
+
```
|
|
118
100
|
|
|
119
|
-
|
|
101
|
+
```powershell
|
|
102
|
+
irm https://raw.githubusercontent.com/GhostPawJS/affinity/main/install.ps1 | iex
|
|
103
|
+
```
|
|
120
104
|
|
|
121
105
|
```sh
|
|
122
106
|
mise use -g github:GhostPawJS/affinity
|
|
@@ -155,8 +139,8 @@ packages:
|
|
|
155
139
|
- name: ghostpaw-affinity
|
|
156
140
|
```
|
|
157
141
|
|
|
158
|
-
|
|
159
|
-
[build attestation](https://cli.github.com/manual/gh_attestation_verify):
|
|
142
|
+
`SHA256SUMS` covers every archive and `server.mcpb`. To verify a downloaded
|
|
143
|
+
archive's [build attestation](https://cli.github.com/manual/gh_attestation_verify):
|
|
160
144
|
|
|
161
145
|
```sh
|
|
162
146
|
gh attestation verify <archive> -R GhostPawJS/affinity
|
|
@@ -169,32 +153,99 @@ download on macOS, remove quarantine with
|
|
|
169
153
|
Linux binaries require glibc 2.28+; use npx on Alpine.
|
|
170
154
|
See the [binary build workflow](.github/workflows/release-binaries.yml).
|
|
171
155
|
|
|
172
|
-
|
|
156
|
+
Each archive is roughly 40-46 MB (the binary embeds the Node runtime, 105-150 MB
|
|
157
|
+
unpacked); the npm package is about 2 MB unpacked. Every release, including the
|
|
158
|
+
one-liners above, is installed and run on ubuntu-24.04, macos-15 and
|
|
159
|
+
windows-2025 by the [install check](.github/workflows/install-check.yml).
|
|
160
|
+
|
|
161
|
+
## MCP server
|
|
173
162
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
| linux-x64 | 41.7 MB tar.gz | 117.6 MB |
|
|
177
|
-
| linux-arm64 | 41.2 MB tar.gz | 115.3 MB |
|
|
178
|
-
| darwin-arm64 | 44.9 MB tar.gz | 146.8 MB |
|
|
179
|
-
| darwin-x64 | 46.4 MB tar.gz | 149.7 MB |
|
|
180
|
-
| windows-x64 | 38.4 MB zip | 105.7 MB |
|
|
163
|
+
Every client below starts the same stdio server: `ghostpaw-affinity mcp`.
|
|
164
|
+
Without the binary, use `npx -y @ghostpaw/affinity mcp` as the command instead.
|
|
181
165
|
|
|
182
|
-
|
|
183
|
-
installed and run on ubuntu-24.04, macos-15 and windows-2025 by the
|
|
184
|
-
[install check](.github/workflows/install-check.yml).
|
|
166
|
+
**Claude Code**
|
|
185
167
|
|
|
186
|
-
|
|
168
|
+
```bash
|
|
169
|
+
claude mcp add ghostpaw-affinity -- ghostpaw-affinity mcp
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
or as a plugin, which also installs the skill:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
/plugin marketplace add GhostPawJS/affinity
|
|
176
|
+
/plugin install ghostpaw-affinity@ghostpaw-affinity
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Codex CLI** (`~/.codex/config.toml`)
|
|
180
|
+
|
|
181
|
+
```toml
|
|
182
|
+
[mcp_servers.ghostpaw-affinity]
|
|
183
|
+
command = "ghostpaw-affinity"
|
|
184
|
+
args = ["mcp"]
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Cursor** (`.cursor/mcp.json`), **Claude Desktop** (`claude_desktop_config.json`)
|
|
188
|
+
or a project `.mcp.json`:
|
|
189
|
+
|
|
190
|
+
```json
|
|
191
|
+
{
|
|
192
|
+
"mcpServers": {
|
|
193
|
+
"ghostpaw-affinity": {
|
|
194
|
+
"command": "ghostpaw-affinity",
|
|
195
|
+
"args": ["mcp"]
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Claude Desktop users can also install `server.mcpb` from the
|
|
202
|
+
[latest GitHub release](https://github.com/GhostPawJS/affinity/releases/latest).
|
|
203
|
+
A Dockerfile is included for container hosts:
|
|
204
|
+
`docker build -t ghostpaw-affinity . && docker run -i --rm -v affinity:/data ghostpaw-affinity`.
|
|
205
|
+
|
|
206
|
+
The server speaks MCP 2026-07-28 (stateless, `server/discover`) and the
|
|
207
|
+
initialize-based revisions 2025-11-25, 2025-06-18, 2025-03-26 and 2024-11-05.
|
|
208
|
+
|
|
209
|
+
### Agent Skill
|
|
210
|
+
|
|
211
|
+
`SKILL.md` (repo root) and `skills/affinity/SKILL.md` follow the
|
|
212
|
+
[Agent Skills](https://agentskills.io) format and ship in the npm package.
|
|
213
|
+
Copy `skills/affinity/` into your agent's skills folder, or print it:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
ghostpaw-affinity skill > SKILL.md
|
|
217
|
+
ghostpaw-affinity skill --list # workflow guides
|
|
218
|
+
ghostpaw-affinity skill bootstrap-and-cold-start
|
|
219
|
+
```
|
|
187
220
|
|
|
188
221
|
## CLI
|
|
189
222
|
|
|
223
|
+
```sh
|
|
224
|
+
export GHOSTPAW_AFFINITY_DB=~/crm/affinity.db # or --db <path>
|
|
225
|
+
ghostpaw-affinity contact create '{"name":"Fox","kind":"human","bootstrapOwner":true}'
|
|
226
|
+
ghostpaw-affinity search "jana" # names, identities, tags, attributes, roles, events
|
|
227
|
+
ghostpaw-affinity contact create '{"name":"Jana Petersen","kind":"human"}'
|
|
228
|
+
ghostpaw-affinity identity add --contact '{"contactId":2}' --input '{"type":"email","value":"jana@example.com"}'
|
|
229
|
+
ghostpaw-affinity event record --kind interaction --input '{"type":"conversation","occurredAt":"today","summary":"Call re pilot","significance":6,"participants":[{"contactId":2,"role":"recipient","directionality":"mutual"}]}'
|
|
230
|
+
ghostpaw-affinity commitment record --input '{"commitmentType":"promise","occurredAt":"today","dueAt":"+3d","summary":"Send proposal","significance":6,"participants":[{"contactId":2,"role":"recipient"}]}'
|
|
231
|
+
ghostpaw-affinity attribute set --target '{"kind":"contact","contact":{"contactId":2}}' --name tag:gastro --value null
|
|
232
|
+
ghostpaw-affinity review contacts.list --tag gastro
|
|
233
|
+
ghostpaw-affinity review contacts.list --attribute pipeline_stage=proposal
|
|
234
|
+
ghostpaw-affinity review commitments.open # overdue promises are flagged
|
|
235
|
+
ghostpaw-affinity review links.radar # who is drifting, with reasons
|
|
236
|
+
ghostpaw-affinity show contact_profile --contact '{"contactId":2}'
|
|
237
|
+
ghostpaw-affinity contact export --contact '{"contactId":2}' # omit --contact for the whole database
|
|
238
|
+
ghostpaw-affinity contact delete --contact '{"contactId":2}' --confirm
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
`ghostpaw-affinity skill` prints the full cheat sheet; `skill --list` and
|
|
242
|
+
`skill <guide>` print the workflow guides.
|
|
243
|
+
|
|
190
244
|
```text
|
|
191
|
-
ghostpaw-affinity search <query>
|
|
192
|
-
ghostpaw-affinity review <view>
|
|
245
|
+
ghostpaw-affinity search <query> [--tag T] [--attribute name[=value]]
|
|
246
|
+
ghostpaw-affinity review <view> [--tag T] [--attribute name[=value]]
|
|
193
247
|
ghostpaw-affinity show <owner_profile|contact_profile|link> [--contact JSON --link JSON]
|
|
194
|
-
ghostpaw-affinity contact create
|
|
195
|
-
ghostpaw-affinity contact revise <contact-json> --patch JSON
|
|
196
|
-
ghostpaw-affinity contact lifecycle <contact-json> <lifecycleState>
|
|
197
|
-
ghostpaw-affinity contact merge [flags]
|
|
248
|
+
ghostpaw-affinity contact create|revise|lifecycle|export|delete|merge
|
|
198
249
|
ghostpaw-affinity identity add|revise|verify|remove [flags]
|
|
199
250
|
ghostpaw-affinity relationship add|bond|state|tie|untie [flags]
|
|
200
251
|
ghostpaw-affinity commitment record|resolve [flags]
|
|
@@ -205,44 +256,50 @@ ghostpaw-affinity duplicate dismiss|undismiss [flags]
|
|
|
205
256
|
ghostpaw-affinity mcp|skill|tools|describe|call|completions|version|help
|
|
206
257
|
```
|
|
207
258
|
|
|
208
|
-
There are
|
|
259
|
+
There are 29 domain commands. `review` accepts the existing view names,
|
|
209
260
|
including `contacts.list`, `contacts.duplicates` and `dates.upcoming`.
|
|
210
261
|
`show` selects an inspection kind; contact and link locators are JSON objects.
|
|
211
|
-
Use `help contact` or `contact create --help` for schema-derived help
|
|
212
|
-
Nested payloads use JSON or `@path`
|
|
262
|
+
Use `help contact` or `contact create --help` for schema-derived help; a
|
|
263
|
+
mistyped command suggests the closest one. Nested payloads use JSON or `@path`
|
|
264
|
+
to read a file; repeated array flags accept JSON objects
|
|
265
|
+
(`--entries '{"name":"a","value":"x"}'`) or one JSON array.
|
|
266
|
+
|
|
267
|
+
Every time field accepts epoch milliseconds, ISO 8601 with `Z` or an offset,
|
|
268
|
+
`YYYY-MM-DD`, `DD.MM.YYYY` (CLI), `today`, `tomorrow`, `yesterday` and signed day offsets
|
|
269
|
+
such as `+3d` or `-2d`. On the CLI, date-only values use local time (midnight,
|
|
270
|
+
or end of day for `dueAt`); through MCP and the tool facade they use UTC.
|
|
213
271
|
|
|
214
272
|
Global flags: `--db <path>`, `--json`, `--quiet`, `--compact`,
|
|
215
273
|
`--help`/`-h`, `--version`/`-V`/`-v`, `--no-color`.
|
|
216
|
-
`NO_COLOR` is accepted
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
274
|
+
`NO_COLOR` is accepted. In a terminal, commands print a readable summary with
|
|
275
|
+
names and dates. With `--json` or piped stdout they print the tool result as
|
|
276
|
+
JSON with ISO date siblings and floats rounded to three decimals; `--compact`
|
|
277
|
+
removes indentation and empty receipt arrays. `--quiet` suppresses stdout.
|
|
278
|
+
Writes list what changed in `data.changes`, and creates warn about likely
|
|
279
|
+
duplicates. Kebab-case flags map to schema properties. `--` ends flags.
|
|
280
|
+
A positional `-`, or piped stdin when no other arguments are given, reads a
|
|
281
|
+
JSON object (`echo '{"name":"Sam","kind":"human"}' | ghostpaw-affinity contact create`).
|
|
282
|
+
Explicit flags override stdin fields.
|
|
223
283
|
Database selection uses `--db`, `GHOSTPAW_AFFINITY_DB`, then
|
|
224
|
-
`~/.ghostpaw/affinity.db
|
|
284
|
+
`~/.ghostpaw/affinity.db`; relative paths resolve against the current
|
|
285
|
+
directory, and `--help` shows the resolved path. A new database is reported on
|
|
286
|
+
stderr. These commands work offline.
|
|
225
287
|
|
|
226
|
-
| Exit |
|
|
288
|
+
| Exit | Result |
|
|
227
289
|
|---|---|
|
|
228
290
|
| 0 | Success, including no_op |
|
|
229
|
-
| 1 |
|
|
230
|
-
| 2 | Usage or
|
|
291
|
+
| 1 | Other tool error |
|
|
292
|
+
| 2 | Usage, schema or invalid input |
|
|
231
293
|
| 3 | Clarification needed or not found |
|
|
232
|
-
| 4 | Conflict or version mismatch |
|
|
294
|
+
| 4 | Conflict, already resolved or version mismatch |
|
|
233
295
|
| 70 | Internal error |
|
|
234
296
|
|
|
235
297
|
Errors go to stderr. With `--json`, errors also print to stdout.
|
|
236
|
-
|
|
237
|
-
|
|
298
|
+
`--version` names the variant: `affinity 0.5.0 (binary, linux-x64)`,
|
|
299
|
+
`(npm)` or `(library)`. Legacy `tools [--json]`, `describe <tool>`,
|
|
300
|
+
`call <tool> [JSON|-]` and `<tool_name> --parameter value` remain available.
|
|
238
301
|
`completions bash|zsh|fish` prints shell scripts.
|
|
239
302
|
|
|
240
|
-
```sh
|
|
241
|
-
ghostpaw-affinity contact create '{"name":"Sam","kind":"human"}' --db /tmp/affinity-example.db --json
|
|
242
|
-
ghostpaw-affinity search Sam --db /tmp/affinity-example.db --json
|
|
243
|
-
ghostpaw-affinity review contacts.list --db /tmp/affinity-example.db --json
|
|
244
|
-
```
|
|
245
|
-
|
|
246
303
|
## Quick Start
|
|
247
304
|
|
|
248
305
|
```ts
|