synomem 0.1.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/AGENTS.md +42 -0
- package/ARCHITECTURE.md +126 -0
- package/CHANGELOG.md +35 -0
- package/CODE_OF_CONDUCT.md +29 -0
- package/CONTRIBUTING.md +48 -0
- package/LICENSE +21 -0
- package/README.md +247 -0
- package/SECURITY.md +117 -0
- package/dist/backend.d.ts +9 -0
- package/dist/backend.d.ts.map +1 -0
- package/dist/backend.js +60 -0
- package/dist/backend.js.map +1 -0
- package/dist/cli.d.ts +34 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1040 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +168 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +1031 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +33 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +153 -0
- package/dist/config.js.map +1 -0
- package/dist/credentials.d.ts +36 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +127 -0
- package/dist/credentials.js.map +1 -0
- package/dist/errors.d.ts +9 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +60 -0
- package/dist/errors.js.map +1 -0
- package/dist/fs-utils.d.ts +7 -0
- package/dist/fs-utils.d.ts.map +1 -0
- package/dist/fs-utils.js +68 -0
- package/dist/fs-utils.js.map +1 -0
- package/dist/import.d.ts +655 -0
- package/dist/import.d.ts.map +1 -0
- package/dist/import.js +226 -0
- package/dist/import.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/index.d.ts +14 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +698 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp-server.d.ts +3 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +45 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/oauth.d.ts +27 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +201 -0
- package/dist/oauth.js.map +1 -0
- package/dist/ports/projections.d.ts +6 -0
- package/dist/ports/projections.d.ts.map +1 -0
- package/dist/ports/projections.js +2 -0
- package/dist/ports/projections.js.map +1 -0
- package/dist/ports/repository.d.ts +31 -0
- package/dist/ports/repository.d.ts.map +1 -0
- package/dist/ports/repository.js +2 -0
- package/dist/ports/repository.js.map +1 -0
- package/dist/projections.d.ts +24 -0
- package/dist/projections.d.ts.map +1 -0
- package/dist/projections.js +531 -0
- package/dist/projections.js.map +1 -0
- package/dist/remote.d.ts +120 -0
- package/dist/remote.d.ts.map +1 -0
- package/dist/remote.js +286 -0
- package/dist/remote.js.map +1 -0
- package/dist/schemas.d.ts +901 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +424 -0
- package/dist/schemas.js.map +1 -0
- package/dist/service.d.ts +126 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +2 -0
- package/dist/service.js.map +1 -0
- package/dist/skill-install.d.ts +34 -0
- package/dist/skill-install.d.ts.map +1 -0
- package/dist/skill-install.js +256 -0
- package/dist/skill-install.js.map +1 -0
- package/dist/storage.d.ts +94 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +1229 -0
- package/dist/storage.js.map +1 -0
- package/dist/types.d.ts +442 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +14 -0
- package/dist/version.js.map +1 -0
- package/docs/cli.md +180 -0
- package/docs/examples.md +70 -0
- package/docs/mcp.md +96 -0
- package/docs/recovery.md +45 -0
- package/docs/releasing.md +61 -0
- package/docs/skill.md +93 -0
- package/docs/storage-format.md +83 -0
- package/openapi/synomem-v1.yaml +674 -0
- package/package.json +100 -0
- package/skills/synomem/SKILL.md +71 -0
- package/skills/synomem/agents/openai.yaml +8 -0
- package/skills/synomem/references/examples.md +28 -0
- package/src/backend.ts +91 -0
- package/src/cli.ts +1623 -0
- package/src/client.ts +1261 -0
- package/src/config.ts +170 -0
- package/src/credentials.ts +194 -0
- package/src/errors.ts +64 -0
- package/src/fs-utils.ts +85 -0
- package/src/import.ts +284 -0
- package/src/index.ts +61 -0
- package/src/mcp/index.ts +973 -0
- package/src/mcp-server.ts +46 -0
- package/src/oauth.ts +252 -0
- package/src/ports/projections.ts +6 -0
- package/src/ports/repository.ts +67 -0
- package/src/projections.ts +624 -0
- package/src/remote.ts +516 -0
- package/src/schemas.ts +457 -0
- package/src/service.ts +140 -0
- package/src/skill-install.ts +332 -0
- package/src/storage.ts +1603 -0
- package/src/types.ts +458 -0
- package/src/version.ts +16 -0
package/docs/cli.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: CLI reference
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# CLI reference
|
|
7
|
+
|
|
8
|
+
`synomem` is noninteractive by default. Add `--json` anywhere for stable machine output and
|
|
9
|
+
`--home <path>` to override `SYNOMEM_HOME` and the default `~/.agents` root.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
synomem --help
|
|
13
|
+
synomem <command> --help
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Initialize and identities
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
synomem init
|
|
20
|
+
synomem agent create codex --name "Codex" --alias reviewer
|
|
21
|
+
synomem agent list
|
|
22
|
+
synomem agent show reviewer
|
|
23
|
+
synomem agent update codex --description "Careful reviewer"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
IDs and aliases use lowercase ASCII letters, digits, and internal hyphens. Aliases never silently
|
|
27
|
+
merge established identities.
|
|
28
|
+
|
|
29
|
+
## Backend and authentication
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
synomem backend show
|
|
33
|
+
synomem backend use remote --url https://api.example.com --workspace 01K...
|
|
34
|
+
synomem auth login --actor-id codex --client-id synomem-cli
|
|
35
|
+
synomem auth status --actor-id codex
|
|
36
|
+
synomem auth logout --actor-id codex
|
|
37
|
+
SYNOMEM_ACCESS_TOKEN=... synomem auth status
|
|
38
|
+
synomem backend use local
|
|
39
|
+
synomem init
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Backend selection is explicit and applies to the CLI and stdio MCP. Remote mode calls the HTTPS
|
|
43
|
+
domain API and does not open SQLite or write local Markdown projections. It does not synchronize or
|
|
44
|
+
merge an existing local history. Switching back to local preserves both stores independently.
|
|
45
|
+
|
|
46
|
+
`auth login` uses OAuth authorization code with PKCE S256, opens the system browser, listens on
|
|
47
|
+
`127.0.0.1:43817` for the validated callback, verifies the resulting credential against the
|
|
48
|
+
configured workspace/actor, and stores it in macOS Keychain or Linux Secret Service
|
|
49
|
+
(`secret-tool`). Register that exact callback URI with the authorization server; use
|
|
50
|
+
`--callback-port` only when the public client is registered with another fixed port.
|
|
51
|
+
|
|
52
|
+
Pass `--actor-kind` when the identity is not an agent. `SYNOMEM_OAUTH_CLIENT_ID` can supply the
|
|
53
|
+
public client ID. `SYNOMEM_ACCESS_TOKEN` remains the headless/CI override and is never persisted or
|
|
54
|
+
printed. Stored refresh tokens are rotated when the authorization server returns a replacement.
|
|
55
|
+
Use narrowly scoped credentials and avoid shell history or committed environment files.
|
|
56
|
+
|
|
57
|
+
### One-way local import
|
|
58
|
+
|
|
59
|
+
Only a human workspace owner or administrator with `synomem:workspace:admin` may import. Preview a
|
|
60
|
+
fresh, consistent read-only SQLite snapshot first, then confirm the exact checksum-bound plan:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
synomem remote import --from-home /path/to/local-home --actor-id troy --preview
|
|
64
|
+
synomem remote import --from-home /path/to/local-home --actor-id troy --confirm <plan-id>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The first hosted importer accepts at most 5 MiB and 100,000 events, and only an empty destination
|
|
68
|
+
workspace. Plans expire after 15 minutes. Confirmation creates a new snapshot; it fails if the
|
|
69
|
+
source changed after preview. The source is never rewritten or deleted, backend selection is not
|
|
70
|
+
changed, and a successful confirmation may be safely retried with the same plan and bundle.
|
|
71
|
+
|
|
72
|
+
## Kudos
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
synomem kudos give codex \
|
|
76
|
+
--from gracie --actor-kind agent \
|
|
77
|
+
--title "Caught a continuity contradiction" \
|
|
78
|
+
--reason "Found conflicting requirements before implementation." \
|
|
79
|
+
--tag review --evidence task:E17 --idempotency-key gracie-codex-e17
|
|
80
|
+
|
|
81
|
+
synomem kudos list --recipient codex
|
|
82
|
+
synomem kudos show <kudos-id>
|
|
83
|
+
synomem kudos acknowledge <kudos-id> --as codex
|
|
84
|
+
synomem kudos revoke <kudos-id> --as gracie --actor-kind agent --reason "Corrected."
|
|
85
|
+
synomem kudos wins codex --print
|
|
86
|
+
synomem kudos stats
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Memos
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
synomem memo send codex --from gracie \
|
|
93
|
+
--subject "Review follow-up" --body "Please recheck the migration."
|
|
94
|
+
synomem memo list --participant codex --status unread
|
|
95
|
+
synomem memo show <memo-id>
|
|
96
|
+
synomem memo read <memo-id> --as codex
|
|
97
|
+
synomem memo archive <memo-id> --as codex
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Sending to the actor's own agent ID is valid future-self communication. Sent content is immutable;
|
|
101
|
+
send a correction rather than editing history.
|
|
102
|
+
|
|
103
|
+
## Notes
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
synomem note create --as codex \
|
|
107
|
+
--title "Release invariant" --body "Never publish without explicit authorization."
|
|
108
|
+
synomem note list --owner codex
|
|
109
|
+
synomem note show <note-id>
|
|
110
|
+
synomem note revise <note-id> --as codex --expected-version 1 --body "Revised text"
|
|
111
|
+
synomem note archive <note-id> --as codex
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Agents may mutate only their own notes. Revisions require the last-read version and fail with
|
|
115
|
+
`REVISION_CONFLICT` if state changed concurrently.
|
|
116
|
+
|
|
117
|
+
## Todos
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
synomem todo create codex --from gracie --title "Review migration" --due-date 2026-09-15
|
|
121
|
+
synomem todo create codex --from gracie --title "Join review" \
|
|
122
|
+
--due-at 2026-09-15T14:00:00-05:00 --time-zone America/Chicago
|
|
123
|
+
synomem todo list --assignee codex --status open
|
|
124
|
+
synomem todo show <todo-id>
|
|
125
|
+
synomem todo accept <todo-id> --as codex
|
|
126
|
+
synomem todo reject <todo-id> --as codex --reason "Outside current scope."
|
|
127
|
+
synomem todo update <todo-id> --as codex --expected-version 2 --priority 2
|
|
128
|
+
synomem todo complete <todo-id> --as codex
|
|
129
|
+
synomem todo reopen <todo-id> --as codex
|
|
130
|
+
synomem todo cancel <todo-id> --as codex --reason "Superseded."
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Todos assigned by another actor begin `assigned` and cannot be worked or completed until the
|
|
134
|
+
assignee explicitly accepts them. Rejection is preserved as a lifecycle event. Self-created agent
|
|
135
|
+
todos begin open. Date-only deadlines do not invent a time; timed deadlines require both an RFC 3339
|
|
136
|
+
offset datetime and an IANA time zone.
|
|
137
|
+
|
|
138
|
+
## Unified discovery and inbox
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
synomem inbox codex
|
|
142
|
+
synomem list --kind memo --kind todo --participant codex --limit 10
|
|
143
|
+
synomem changes --after <opaque-watermark>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
List results are compact, default to 10, allow at most 50, and omit full detail fields. Changes
|
|
147
|
+
default to 20 and allow at most 100. Both apply an approximate 24 KiB budget and return opaque
|
|
148
|
+
continuation state. Fetch full detail with the appropriate `kudos show`, `memo show`, `note show`,
|
|
149
|
+
or `todo show` command.
|
|
150
|
+
|
|
151
|
+
## Administration
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
synomem doctor
|
|
155
|
+
synomem rebuild
|
|
156
|
+
synomem backup ./synomem-backup.sqlite3
|
|
157
|
+
synomem export --format json|jsonl|markdown
|
|
158
|
+
synomem mcp --actor-id codex --actor-kind agent --actor-name "Codex"
|
|
159
|
+
synomem skill install --runtime codex --actor-id codex --actor-name "Codex" --yes
|
|
160
|
+
synomem skill install --runtime hermes --actor-id mycroft --actor-name "Mycroft" --yes
|
|
161
|
+
synomem skill status
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Skill runtime names are `claude`, `codex`, `hermes`, `openclaw`, `cursor`, and `grok`;
|
|
165
|
+
`grokbot` is accepted as an alias for local Grok Build. Omit `--runtime` to inspect every detected
|
|
166
|
+
runtime. Install and uninstall remain dry runs unless `--yes` is present.
|
|
167
|
+
|
|
168
|
+
Backups never overwrite an existing destination. JSON and JSONL are the recovery formats when a
|
|
169
|
+
canonical row is malformed or newer than the installed package.
|
|
170
|
+
|
|
171
|
+
## Exit codes
|
|
172
|
+
|
|
173
|
+
| Code | Meaning |
|
|
174
|
+
| ---: | ----------------------------------------------------- |
|
|
175
|
+
| 0 | Success |
|
|
176
|
+
| 1 | Unexpected internal failure |
|
|
177
|
+
| 2 | Invalid arguments, configuration, conflict, or input |
|
|
178
|
+
| 3 | Agent or item not found |
|
|
179
|
+
| 4 | Policy or read-only denial |
|
|
180
|
+
| 5 | Database, schema, remote transport, or health failure |
|
package/docs/examples.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: Examples
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Examples
|
|
7
|
+
|
|
8
|
+
All examples use fictional identities and an isolated temporary home.
|
|
9
|
+
|
|
10
|
+
## Initialize identities
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
export SYNOMEM_HOME="$(mktemp -d)/.agents"
|
|
14
|
+
|
|
15
|
+
synomem init
|
|
16
|
+
synomem agent create atlas --name "Atlas"
|
|
17
|
+
synomem agent create beacon --name "Beacon"
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Four distinct durable operations
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
synomem kudos give beacon --from atlas --actor-kind agent \
|
|
24
|
+
--title "Found the hidden retry race" \
|
|
25
|
+
--reason "Produced a minimal reproduction before release." \
|
|
26
|
+
--tag reliability --idempotency-key atlas-beacon-kudos-17
|
|
27
|
+
|
|
28
|
+
synomem memo send beacon --from atlas --actor-kind agent \
|
|
29
|
+
--subject "Requirement changed" \
|
|
30
|
+
--body "Use the append-only transition described in ADR-17."
|
|
31
|
+
|
|
32
|
+
synomem note create --as atlas --actor-kind agent \
|
|
33
|
+
--title "Repository convention" \
|
|
34
|
+
--body "All timestamps retain an explicit offset."
|
|
35
|
+
|
|
36
|
+
synomem todo create beacon --from atlas --actor-kind agent \
|
|
37
|
+
--title "Review ADR-17" --priority 2 --due-date 2026-09-15
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The cross-agent todo begins as `assigned`. Beacon must explicitly accept or reject it:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
synomem todo accept <todo-id> --as beacon --actor-kind agent
|
|
44
|
+
# or
|
|
45
|
+
synomem todo reject <todo-id> --as beacon --actor-kind agent --reason "Wrong owner"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Unified bounded reads
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
synomem inbox beacon
|
|
52
|
+
synomem list --participant beacon --limit 20 --json
|
|
53
|
+
synomem changes --after <previous-watermark> --limit 20 --json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Persist the returned change watermark and pass it on the next poll. Use a domain `show` command when
|
|
57
|
+
full content is needed; list and change feeds intentionally return compact summaries.
|
|
58
|
+
|
|
59
|
+
## Idempotent retry
|
|
60
|
+
|
|
61
|
+
If a mutation response is interrupted, repeat it as the same actor with the same stable idempotency
|
|
62
|
+
key. Synomem returns the original result with `deduplicated: true` instead of creating another item.
|
|
63
|
+
|
|
64
|
+
## Demo script
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npm run demo
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The demo builds the package, uses a temporary home, records fictional data, and removes that data.
|
package/docs/mcp.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: MCP server
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# MCP server
|
|
7
|
+
|
|
8
|
+
`synomem-mcp` is an actor-bound stdio server built with the official TypeScript SDK. It opens no
|
|
9
|
+
network listener.
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
SYNOMEM_ACTOR_ID=codex
|
|
13
|
+
SYNOMEM_ACTOR_KIND=agent
|
|
14
|
+
SYNOMEM_ACTOR_NAME=Codex
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Malformed or missing identity configuration fails startup. The server inserts the bound identity
|
|
18
|
+
into mutations; callers cannot override it in tool arguments.
|
|
19
|
+
|
|
20
|
+
## Registration
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
codex mcp add synomem \
|
|
24
|
+
--env SYNOMEM_ACTOR_ID=codex \
|
|
25
|
+
--env SYNOMEM_ACTOR_KIND=agent \
|
|
26
|
+
--env SYNOMEM_ACTOR_NAME=Codex \
|
|
27
|
+
-- synomem-mcp
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Add `--env SYNOMEM_HOME=/absolute/shared/path` when not using `~/.agents`.
|
|
31
|
+
|
|
32
|
+
When that home selects a remote backend, the same stdio MCP command uses the remote API and creates
|
|
33
|
+
no local SQLite database or projections. Run `synomem auth login --actor-id <id> --client-id <id>`
|
|
34
|
+
first, or provide `SYNOMEM_ACCESS_TOKEN` to the MCP process as a secret environment variable. The
|
|
35
|
+
configured `--actor-*` values select the matching OS credential entry and describe the expected
|
|
36
|
+
binding, but the hosted service remains authoritative and derives actor/workspace permissions from
|
|
37
|
+
the token; request bodies cannot override them.
|
|
38
|
+
|
|
39
|
+
## Tools
|
|
40
|
+
|
|
41
|
+
Shared bounded reads:
|
|
42
|
+
|
|
43
|
+
```text
|
|
44
|
+
synomem_list synomem_get
|
|
45
|
+
synomem_changes synomem_inbox
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Purpose-specific writes:
|
|
49
|
+
|
|
50
|
+
```text
|
|
51
|
+
synomem_kudos_give synomem_kudos_acknowledge synomem_kudos_revoke
|
|
52
|
+
synomem_memo_send synomem_memo_read synomem_memo_archive
|
|
53
|
+
synomem_note_create synomem_note_revise synomem_note_archive
|
|
54
|
+
synomem_todo_create synomem_todo_update synomem_todo_complete
|
|
55
|
+
synomem_todo_accept synomem_todo_reject synomem_todo_reopen
|
|
56
|
+
synomem_todo_cancel
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Focused kudos reads and administration remain available:
|
|
60
|
+
|
|
61
|
+
```text
|
|
62
|
+
synomem_kudos_list synomem_kudos_get synomem_kudos_changes
|
|
63
|
+
synomem_kudos_stats synomem_agent_list synomem_agent_create
|
|
64
|
+
synomem_doctor synomem_rebuild
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Agent creation and rebuild are disabled by default. Every tool declares precise schemas, stable
|
|
68
|
+
errors, structured and concise text content, the bound actor, and MCP behavior annotations.
|
|
69
|
+
|
|
70
|
+
`synomem_list` returns 10 compact summaries by default and at most 50. `synomem_changes` returns 20
|
|
71
|
+
changes by default and at most 100. Both stop around a 24 KiB item-data budget. Bodies, reasons,
|
|
72
|
+
evidence, descriptions, source, and metadata require one explicit `synomem_get`.
|
|
73
|
+
|
|
74
|
+
## Resources
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
synomem://agents
|
|
78
|
+
synomem://agents/<agent-id>/profile
|
|
79
|
+
synomem://agents/<agent-id>/wins
|
|
80
|
+
synomem://agents/<agent-id>/inbox
|
|
81
|
+
synomem://items/<item-id>
|
|
82
|
+
synomem://events/<event-id>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Resources apply the same participant and visibility policy as tools. Agents may read only their own
|
|
86
|
+
inbox resource. Canonical event resources authorize against their aggregate before returning data.
|
|
87
|
+
|
|
88
|
+
## Policy
|
|
89
|
+
|
|
90
|
+
Edit `<home>/synomem/config.json` while writers are stopped. Safe defaults deny self-kudos, MCP
|
|
91
|
+
identity creation, and MCP rebuild. Notes are unconditionally owner-private in V1. Cross-agent todo assignment is enabled; ownership and
|
|
92
|
+
participant rules still apply.
|
|
93
|
+
|
|
94
|
+
Human actors have local administrative authority. Agent actors manage only their own note, recipient
|
|
95
|
+
memo state, and todos they created or received. System actors have no implicit authority. The
|
|
96
|
+
filesystem owner remains the ultimate local authority.
|
package/docs/recovery.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: Backup and recovery
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Backup and recovery
|
|
7
|
+
|
|
8
|
+
## Create a consistent backup
|
|
9
|
+
|
|
10
|
+
Do not copy a live WAL database directly. Ask SQLite to create a consistent snapshot:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
synomem backup ./synomem-backup.sqlite3
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The destination must not exist. Synomem creates the backup with owner-only permissions where POSIX file modes are available.
|
|
17
|
+
|
|
18
|
+
## Restore without risking the active home
|
|
19
|
+
|
|
20
|
+
Stop Synomem writers before switching homes. Always validate a backup in a new directory; do not overwrite or delete the current database during validation.
|
|
21
|
+
|
|
22
|
+
On macOS or Linux:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
RESTORE_HOME="$PWD/restored-agents"
|
|
26
|
+
mkdir -p "$RESTORE_HOME/synomem"
|
|
27
|
+
chmod 700 "$RESTORE_HOME" "$RESTORE_HOME/synomem"
|
|
28
|
+
install -m 600 ./synomem-backup.sqlite3 "$RESTORE_HOME/synomem/synomem.sqlite3"
|
|
29
|
+
synomem --home "$RESTORE_HOME" doctor
|
|
30
|
+
synomem --home "$RESTORE_HOME" rebuild
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
On Windows PowerShell:
|
|
34
|
+
|
|
35
|
+
```powershell
|
|
36
|
+
$RestoreRoot = Join-Path (Get-Location) "restored-agents"
|
|
37
|
+
New-Item -ItemType Directory -Force (Join-Path $RestoreRoot "synomem")
|
|
38
|
+
Copy-Item ".\synomem-backup.sqlite3" (Join-Path $RestoreRoot "synomem\synomem.sqlite3")
|
|
39
|
+
synomem --home $RestoreRoot doctor
|
|
40
|
+
synomem --home $RestoreRoot rebuild
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Both commands must succeed. Inspect representative `WINS.md` and inbox files, then point `SYNOMEM_HOME` at the restored directory and restart agents. Keep the previous home unchanged until the restored installation has been exercised successfully, so rollback only requires switching the configured home back.
|
|
44
|
+
|
|
45
|
+
If `doctor` reports an unsupported event, upgrade Synomem before writing. JSON and JSONL export preserve raw canonical payloads even when the installed version cannot interpret them.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: Releasing
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Releasing
|
|
7
|
+
|
|
8
|
+
Publishing is intentionally separate from ordinary CI and requires maintainer authorization.
|
|
9
|
+
|
|
10
|
+
## Bootstrap release
|
|
11
|
+
|
|
12
|
+
An npm trusted publisher can be configured only after the package exists in the registry. The first
|
|
13
|
+
release therefore requires an explicitly authorized, interactive publish by the maintainer:
|
|
14
|
+
|
|
15
|
+
1. Confirm `npm whoami` reports the intended account and account-level two-factor authentication is enabled.
|
|
16
|
+
2. Run every quality gate and inspect `npm publish --dry-run`.
|
|
17
|
+
3. Publish once with `npm publish --access public`; complete the interactive authentication prompt.
|
|
18
|
+
4. Verify the package name, version, files, binaries, and repository link on npm before continuing.
|
|
19
|
+
|
|
20
|
+
Create the `v0.1.0` GitHub Release only after this bootstrap publish succeeds. The release workflow
|
|
21
|
+
reruns the gates, verifies the tag, detects that the exact registry version already exists, and
|
|
22
|
+
idempotently skips the duplicate publish.
|
|
23
|
+
|
|
24
|
+
## Trusted publishing setup
|
|
25
|
+
|
|
26
|
+
After the bootstrap package exists:
|
|
27
|
+
|
|
28
|
+
1. On npmjs.com, configure a trusted publisher for:
|
|
29
|
+
- GitHub owner: `Coaden`
|
|
30
|
+
- Repository: `synomem`
|
|
31
|
+
- Workflow filename: `release.yml`
|
|
32
|
+
- Environment: `npm` if environment protection is enabled
|
|
33
|
+
- Allowed action: `npm publish`
|
|
34
|
+
2. In GitHub, create an `npm` environment and preferably require maintainer approval.
|
|
35
|
+
3. Enable GitHub Pages with **GitHub Actions** as the source.
|
|
36
|
+
|
|
37
|
+
The release workflow uses OIDC trusted publishing, requires no long-lived npm token, and receives only `contents: read` and `id-token: write` permissions. npm trusted publishing generates provenance automatically for this public repository/package combination.
|
|
38
|
+
|
|
39
|
+
## Subsequent release checklist
|
|
40
|
+
|
|
41
|
+
1. Update `CHANGELOG.md` and remove the `Unreleased` placeholder for the version.
|
|
42
|
+
2. Set the version with `npm version <major|minor|patch>` and review the generated commit/tag.
|
|
43
|
+
3. Run:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm ci
|
|
47
|
+
npm run format:check
|
|
48
|
+
npm run lint
|
|
49
|
+
npm run typecheck
|
|
50
|
+
npm test
|
|
51
|
+
npm run test:coverage
|
|
52
|
+
npm run pack:check
|
|
53
|
+
npm pack --dry-run
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
4. Push the version commit and tag.
|
|
57
|
+
5. Create an intentional GitHub Release for the tag.
|
|
58
|
+
6. Review the `Release npm package` workflow and protected environment approval.
|
|
59
|
+
7. Verify the npm page, provenance, tarball contents, both binaries, package exports, repository URL, and release notes.
|
|
60
|
+
|
|
61
|
+
Do not publish from a developer laptop as the normal path, do not add an `NPM_TOKEN` fallback casually, and do not reuse the Pages workflow for npm publication.
|
package/docs/skill.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: Agent skill
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Agent skill
|
|
7
|
+
|
|
8
|
+
The distributable skill lives at [`skills/synomem`](https://github.com/Coaden/synomem/blob/main/skills/synomem/SKILL.md) and is included in the npm tarball. It teaches skill-aware agents when durable recognition is appropriate, how to use MCP or CLI, how to sanitize evidence, and how to retry safely.
|
|
9
|
+
|
|
10
|
+
## Repository-local installation
|
|
11
|
+
|
|
12
|
+
Copy or link the skill into the runtime-specific repository skill directory. This keeps setup reviewable and scoped to one project.
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
<repository>/.codex/skills/synomem/SKILL.md
|
|
16
|
+
<repository>/.claude/skills/synomem/SKILL.md
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## User installation
|
|
20
|
+
|
|
21
|
+
The CLI verifies and manages these user-level layouts:
|
|
22
|
+
|
|
23
|
+
| Runtime | Skill destination | Home override |
|
|
24
|
+
| ----------- | ---------------------------- | ------------------------------ |
|
|
25
|
+
| Claude Code | `~/.claude/skills/synomem` | `CLAUDE_CONFIG_DIR` |
|
|
26
|
+
| Codex | `~/.codex/skills/synomem` | `CODEX_HOME` |
|
|
27
|
+
| Hermes | `~/.hermes/skills/synomem` | `HERMES_HOME` (active profile) |
|
|
28
|
+
| OpenClaw | `~/.openclaw/skills/synomem` | `OPENCLAW_STATE_DIR` |
|
|
29
|
+
| Cursor | `~/.cursor/skills/synomem` | — |
|
|
30
|
+
| Grok Build | `~/.grok/skills/synomem` | `GROK_HOME` |
|
|
31
|
+
|
|
32
|
+
These locations follow the current vendor documentation for [Claude Code](https://code.claude.com/docs/en/skills), [Cursor](https://cursor.com/docs/skills), [Hermes](https://hermes-agent.nousresearch.com/docs/user-guide/features/skills), [OpenClaw](https://docs.openclaw.ai/skills), and [Grok Build](https://docs.x.ai/build/features/skills-plugins-marketplaces). Codex uses its native `$CODEX_HOME/skills` convention.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
synomem skill install # dry-run every detected runtime
|
|
36
|
+
synomem skill install --runtime codex --yes # install one copied skill
|
|
37
|
+
synomem skill install --runtime claude --link --yes # explicit package-linked install
|
|
38
|
+
synomem skill install --runtime hermes --yes # active HERMES_HOME profile
|
|
39
|
+
synomem skill install --runtime openclaw --yes # active OpenClaw state directory
|
|
40
|
+
synomem skill install --runtime cursor --yes
|
|
41
|
+
synomem skill install --runtime grokbot --yes # alias for grok
|
|
42
|
+
synomem skill status
|
|
43
|
+
synomem skill uninstall --runtime claude # dry-run removal
|
|
44
|
+
synomem skill uninstall --runtime claude --yes
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Bare `install` and `uninstall` commands are dry runs. The installer applies only with `--yes`, only when the runtime home already exists, and only to its `skills/synomem` child. Copies carry an ownership/version stamp so `status` can report stale installations after npm updates. Existing unowned directories are conflicts and require explicit `--force`; unrelated sibling skills are never touched.
|
|
48
|
+
|
|
49
|
+
Copy mode is the stable default. `--link` points at the skill inside the installed npm package, which updates with an in-place global package upgrade but may break if that package moves. Run `status` after package updates either way.
|
|
50
|
+
|
|
51
|
+
Copied bundles preserve the packaged file modes so executable helper scripts remain executable.
|
|
52
|
+
Skill content is operational guidance rather than confidential Synomem data and does not use the
|
|
53
|
+
database and projection file-mode policy. The Synomem ownership/version stamp is restricted to the
|
|
54
|
+
local user where POSIX modes are available.
|
|
55
|
+
|
|
56
|
+
Add identity options to print a ready-to-review actor-bound MCP command for Codex, Claude Code,
|
|
57
|
+
Hermes, OpenClaw, or Grok Build:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
synomem skill install --runtime codex --actor-id codex --actor-name "Codex"
|
|
61
|
+
synomem skill install --runtime claude --actor-id claude --actor-name "Claude"
|
|
62
|
+
synomem skill install --runtime openclaw --actor-id mycroft --actor-name "Mycroft"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Cursor discovers skills automatically but currently requires MCP definitions in its global
|
|
66
|
+
`~/.cursor/mcp.json` or project `.cursor/mcp.json`. Merge a `synomem` entry without replacing other
|
|
67
|
+
servers. Use `synomem-mcp` as the command and pass `--actor-id`, `--actor-kind agent`, and
|
|
68
|
+
`--actor-name` as arguments. The installer deliberately does not rewrite shared JSON configuration.
|
|
69
|
+
|
|
70
|
+
Global skill installation changes agent configuration and is always an explicit user action. Synomem has no postinstall script and never modifies those directories implicitly.
|
|
71
|
+
|
|
72
|
+
## MCP and skill roles
|
|
73
|
+
|
|
74
|
+
The skill guides agent decisions; the MCP server performs and enforces operations. Install both for the best experience:
|
|
75
|
+
|
|
76
|
+
1. Install `synomem`.
|
|
77
|
+
2. Create stable profiles with the human CLI.
|
|
78
|
+
3. Register one actor-bound MCP process per runtime.
|
|
79
|
+
4. Install the skill where that runtime discovers skills.
|
|
80
|
+
|
|
81
|
+
When MCP is unavailable, the skill permits using the local `synomem` CLI if command execution is allowed.
|
|
82
|
+
|
|
83
|
+
## Runtime boundaries
|
|
84
|
+
|
|
85
|
+
All supported installers target local filesystem runtimes. A hosted Grok Bot does not automatically
|
|
86
|
+
share the desktop's `~/.agents` database. It can use Synomem only if its persistent machine supports
|
|
87
|
+
Node.js, local stdio MCP, and its own durable Synomem home. Otherwise give it the public
|
|
88
|
+
[`SKILL.md`](https://github.com/Coaden/synomem/blob/main/skills/synomem/SKILL.md) as guidance and do
|
|
89
|
+
not tunnel or copy the live SQLite database.
|
|
90
|
+
|
|
91
|
+
Other harnesses may use the same Agent Skills format, but Synomem does not write to an unverified
|
|
92
|
+
directory. Inspect authoritative documentation or a real installation before copying the packaged
|
|
93
|
+
skill or configuring MCP.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: Storage format
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Storage format
|
|
7
|
+
|
|
8
|
+
## Home layout
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
~/.agents/
|
|
12
|
+
├── synomem/
|
|
13
|
+
│ ├── config.json
|
|
14
|
+
│ ├── synomem.sqlite3
|
|
15
|
+
│ ├── synomem.sqlite3-wal
|
|
16
|
+
│ └── synomem.sqlite3-shm
|
|
17
|
+
└── <agent-id>/
|
|
18
|
+
├── profile.json
|
|
19
|
+
├── WINS.md
|
|
20
|
+
├── MEMORY.md
|
|
21
|
+
├── TODOS.md
|
|
22
|
+
├── inbox/{kudos,memos,todos}/<item-id>.md
|
|
23
|
+
└── NOTES.md
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`SYNOMEM_HOME`, the CLI `--home` option, or the library's `home` option changes the root.
|
|
27
|
+
|
|
28
|
+
`config.json` schema version 3 contains an explicit backend:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{ "kind": "local" }
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
or a remote service location and workspace identifier:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"kind": "remote",
|
|
39
|
+
"baseUrl": "https://synomem.example",
|
|
40
|
+
"workspaceId": "01K..."
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Schema version 2 configurations migrate to the local backend. Remote credentials are not stored in
|
|
45
|
+
this file. The local SQLite client refuses remote configuration rather than creating a shadow local
|
|
46
|
+
database.
|
|
47
|
+
|
|
48
|
+
## SQLite schema
|
|
49
|
+
|
|
50
|
+
Schema version 3 contains:
|
|
51
|
+
|
|
52
|
+
- `events`: canonical append-only validated JSON events with workspace, aggregate, query, and
|
|
53
|
+
monotonic sequence fields;
|
|
54
|
+
- `items_current`: compact cross-type summary and lifecycle state;
|
|
55
|
+
- `kudos_current`: focused recognition summary and acknowledgment/revocation state;
|
|
56
|
+
- `agents` and `aliases`: current identity projections;
|
|
57
|
+
- `projection_manifest`: generated paths eligible for constrained cleanup;
|
|
58
|
+
- `schema_migrations`: applied database migrations.
|
|
59
|
+
|
|
60
|
+
Events use transactionally assigned ingestion sequences for cursors and watermarks. Aggregate
|
|
61
|
+
versions provide optimistic concurrency for notes and todos. Actor-scoped idempotency keys protect
|
|
62
|
+
all retryable mutations.
|
|
63
|
+
|
|
64
|
+
Current tables and files are rebuildable. Full bodies, reasons, evidence, descriptions, source, and
|
|
65
|
+
metadata remain in canonical events and require detail reads. Machine APIs never parse Markdown.
|
|
66
|
+
|
|
67
|
+
## Generated and owned files
|
|
68
|
+
|
|
69
|
+
`profile.json`, `WINS.md`, `MEMORY.md`, `TODOS.md`, and inbox entries are generated. Normal mutations
|
|
70
|
+
synchronize only affected agents; `synomem rebuild` performs full deterministic regeneration.
|
|
71
|
+
Cleanup removes only manifest-listed regular files and never follows symlinks.
|
|
72
|
+
|
|
73
|
+
`NOTES.md` is human-owned, is never placed in the manifest, and is never overwritten. Canonical
|
|
74
|
+
agent notes project to `MEMORY.md`.
|
|
75
|
+
|
|
76
|
+
## Recovery
|
|
77
|
+
|
|
78
|
+
Use `synomem backup` for a consistent SQLite snapshot. Use JSON or JSONL export for portable raw
|
|
79
|
+
recovery, including unsupported or malformed rows. Markdown export may omit rows it cannot safely
|
|
80
|
+
render.
|
|
81
|
+
|
|
82
|
+
Never edit canonical tables, overwrite an active database, copy a live database naively, or
|
|
83
|
+
synchronize it through Git, Dropbox, a network share, or a file-copy tool.
|