synomem 0.7.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +47 -68
  3. package/dist/backend.d.ts +18 -6
  4. package/dist/backend.d.ts.map +1 -1
  5. package/dist/backend.js +55 -41
  6. package/dist/backend.js.map +1 -1
  7. package/dist/cli.d.ts +20 -25
  8. package/dist/cli.d.ts.map +1 -1
  9. package/dist/cli.js +1394 -1281
  10. package/dist/cli.js.map +1 -1
  11. package/dist/configure.d.ts +12 -46
  12. package/dist/configure.d.ts.map +1 -1
  13. package/dist/configure.js +51 -192
  14. package/dist/configure.js.map +1 -1
  15. package/dist/credentials.d.ts +73 -33
  16. package/dist/credentials.d.ts.map +1 -1
  17. package/dist/credentials.js +167 -43
  18. package/dist/credentials.js.map +1 -1
  19. package/dist/discover.d.ts +10 -13
  20. package/dist/discover.d.ts.map +1 -1
  21. package/dist/discover.js +45 -30
  22. package/dist/discover.js.map +1 -1
  23. package/dist/errors.d.ts +1 -1
  24. package/dist/errors.d.ts.map +1 -1
  25. package/dist/errors.js +5 -0
  26. package/dist/errors.js.map +1 -1
  27. package/dist/import.d.ts +3 -0
  28. package/dist/import.d.ts.map +1 -1
  29. package/dist/import.js +3 -0
  30. package/dist/import.js.map +1 -1
  31. package/dist/index.d.ts +9 -7
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +6 -5
  34. package/dist/index.js.map +1 -1
  35. package/dist/mcp/index.d.ts +18 -7
  36. package/dist/mcp/index.d.ts.map +1 -1
  37. package/dist/mcp/index.js +402 -183
  38. package/dist/mcp/index.js.map +1 -1
  39. package/dist/mcp-server.d.ts +5 -1
  40. package/dist/mcp-server.d.ts.map +1 -1
  41. package/dist/mcp-server.js +27 -105
  42. package/dist/mcp-server.js.map +1 -1
  43. package/dist/oauth.d.ts +31 -33
  44. package/dist/oauth.d.ts.map +1 -1
  45. package/dist/oauth.js +178 -125
  46. package/dist/oauth.js.map +1 -1
  47. package/dist/profiles.d.ts +243 -0
  48. package/dist/profiles.d.ts.map +1 -0
  49. package/dist/profiles.js +465 -0
  50. package/dist/profiles.js.map +1 -0
  51. package/dist/project.d.ts +8 -39
  52. package/dist/project.d.ts.map +1 -1
  53. package/dist/project.js +36 -94
  54. package/dist/project.js.map +1 -1
  55. package/dist/remote.d.ts +23 -15
  56. package/dist/remote.d.ts.map +1 -1
  57. package/dist/remote.js +54 -49
  58. package/dist/remote.js.map +1 -1
  59. package/dist/resolvers.d.ts +47 -0
  60. package/dist/resolvers.d.ts.map +1 -0
  61. package/dist/resolvers.js +255 -0
  62. package/dist/resolvers.js.map +1 -0
  63. package/dist/service.d.ts +2 -0
  64. package/dist/service.d.ts.map +1 -1
  65. package/dist/skill-install.d.ts +4 -6
  66. package/dist/skill-install.d.ts.map +1 -1
  67. package/dist/skill-install.js +13 -12
  68. package/dist/skill-install.js.map +1 -1
  69. package/dist/types.d.ts +51 -0
  70. package/dist/types.d.ts.map +1 -1
  71. package/docs/cli.md +173 -196
  72. package/docs/mcp.md +69 -65
  73. package/package.json +1 -1
  74. package/skills/synomem/SKILL.md +30 -4
  75. package/skills/synomem/references/examples.md +14 -0
  76. package/src/backend.ts +66 -64
  77. package/src/cli.ts +2137 -2163
  78. package/src/configure.ts +62 -241
  79. package/src/credentials.ts +208 -84
  80. package/src/discover.ts +60 -36
  81. package/src/errors.ts +5 -0
  82. package/src/import.ts +5 -0
  83. package/src/index.ts +14 -12
  84. package/src/mcp/index.ts +473 -194
  85. package/src/mcp-server.ts +32 -114
  86. package/src/oauth.ts +229 -130
  87. package/src/profiles.ts +644 -0
  88. package/src/project.ts +42 -108
  89. package/src/remote.ts +69 -58
  90. package/src/resolvers.ts +299 -0
  91. package/src/service.ts +2 -0
  92. package/src/skill-install.ts +17 -18
  93. package/src/types.ts +46 -0
package/docs/cli.md CHANGED
@@ -6,273 +6,250 @@ title: CLI reference
6
6
  # CLI reference
7
7
 
8
8
  `synomem` is noninteractive by default. Add `--json` anywhere for stable machine output and
9
- `--home <path>` to override `SYNOMEM_HOME` and the default `~/.synomem` root.
9
+ `--home <path>` to override `SYNOMEM_HOME` and the default `~/.synomem` home.
10
10
 
11
11
  ```bash
12
12
  synomem --help
13
13
  synomem <command> --help
14
14
  ```
15
15
 
16
- ## Setup
17
-
18
- ```bash
19
- synomem config # interactive; picks the backend and sets it up
20
- synomem config init --backend local --yes # the deterministic equivalent
21
- synomem config show # never prints a secret, only where one comes from
16
+ ## Identity: profiles, connections, contexts
17
+
18
+ Every command that reads or writes records acts as exactly one **profile**. A profile names one
19
+ stable **context** — one workspace and one actor — and how to reach it: a local store, or a hosted
20
+ **connection** (a credential). There are no per-command identity flags; `--actor`, `--as`,
21
+ `--from`, `--actor-kind`, `--agent-id` and `SYNOMEM_ACTOR_ID` are refused with a pointer to
22
+ `--profile`.
23
+
24
+ Which profile a command uses, most specific first:
25
+
26
+ 1. `--profile <name>` (or `--preset <name>` for `synomem mcp`)
27
+ 2. `SYNOMEM_PROFILE` / `SYNOMEM_PRESET`
28
+ 3. the nearest project `.synomem/project.json` — it may name a profile or preset, nothing else
29
+ 4. `defaultProfile` in `~/.synomem/profiles.json`
30
+
31
+ Naming a profile that does not exist is an error; it never falls through to the next source.
32
+
33
+ `~/.synomem/profiles.json` holds names and references only — never a secret:
34
+
35
+ ```json
36
+ {
37
+ "version": 1,
38
+ "credentials": {
39
+ "codex-mac": {
40
+ "kind": "oauth",
41
+ "apiUrl": "https://api.synomem.ai",
42
+ "store": "keychain",
43
+ "secretRef": "synomem-3f0c…",
44
+ "connectionId": "con_…",
45
+ "createdAt": "2026-09-23T00:00:00.000Z"
46
+ }
47
+ },
48
+ "profiles": {
49
+ "gracie-eng": { "credentialRef": "codex-mac", "contextId": "ctx_…" },
50
+ "astra-eng": { "credentialRef": "codex-mac", "contextId": "ctx_…" },
51
+ "mike": { "backend": "local", "actorId": "01J…", "contextId": "lctx_…" }
52
+ },
53
+ "harnessPresets": { "codex": ["gracie-eng", "astra-eng"] },
54
+ "defaultProfile": "gracie-eng"
55
+ }
22
56
  ```
23
57
 
24
- For Synomem Cloud with an access key, setup asks the key which workspaces its organization has and
25
- picks one automatically when there is only one — nothing has to be looked up by hand. The key is
26
- piped rather than passed as an argument, because an argument is kept by both the shell history and
27
- the process list:
58
+ Two profiles above share one connection, so one sign-in serves both. Context ids are stable: key
59
+ rotation, a fresh sign-in, or renewed consent never changes them, so profiles keep working.
28
60
 
29
- ```bash
30
- printf '%s' "$SYNOMEM_KEY" | synomem config init \
31
- --backend remote --auth access-key --access-token-stdin --yes
32
- ```
33
-
34
- `--workspace <id>` is still accepted, and is required when there is no key to ask.
35
-
36
- ## Status
61
+ ## Local setup
37
62
 
38
63
  ```bash
39
- synomem backend show # reads the configuration file; connects to nothing
40
- synomem backend status # connects, and reports what actually answered
41
- synomem projection status # local only: do the generated files match the events?
42
- synomem doctor
64
+ synomem setup --backend local --agent gracie --name "Gracie"
65
+ synomem whoami
43
66
  ```
44
67
 
45
- `backend show` and `backend status` are separate on purpose. Someone debugging a broken setup needs
46
- to see what is configured even when nothing can be reached; someone confirming a working setup needs
47
- a connection to have been made. One command doing both would make a printed workspace ID look like a
48
- reachable workspace.
68
+ `setup` creates the local store (if needed), the first agent, and a same-named fixed profile, and
69
+ makes it the default only if none exists. Re-running it is idempotent, and if it was interrupted
70
+ after the agent was created, the next run reuses that agent instead of creating another. It never
71
+ overwrites or rebinds an existing profile.
49
72
 
50
- `projection status` compares the generated files against the manifest Synomem wrote, not against a
51
- directory listing, so a file you put in the projection tree yourself is never reported as drift.
52
- Both `missing` and `unexpected` are repaired by `synomem rebuild`, and neither means an event was
53
- lost: projections are derived, never canonical.
54
-
55
- ## Initialize and identities
73
+ More local agents are independent domain operations; they get a profile only when asked:
56
74
 
57
75
  ```bash
58
- synomem init
59
- synomem agent create codex --name "Codex" --alias reviewer
60
- synomem agent list
61
- synomem agent show reviewer
62
- synomem agent update codex --description "Careful reviewer"
63
- synomem agent resolve Reviewer
64
- synomem agent directory
65
- synomem agent runtime bind codex --runtime claude-code --profile clinic
66
- synomem agent runtime list codex
67
- synomem agent runtime list # every agent that runs anywhere
68
- synomem agent runtime unbind <binding-id>
76
+ synomem agent create codex --name "Codex" # no profile, no default change
77
+ synomem agent create mike --name "Mike" --create-profile # also creates profile "mike"
78
+ synomem profile create codex --local --agent codex # a profile for an existing agent
69
79
  ```
70
80
 
71
- Each agent has an opaque canonical ID, generated at creation and never reused, and a separate
72
- handle -- the name you type. Renaming an agent changes the handle and leaves its history intact,
73
- because every stored event references the ID. `agent create` takes the handle; the ID is generated
74
- and never supplied.
75
-
76
- Handles use lowercase ASCII letters, digits, and internal hyphens. Aliases accept any casing and are
77
- stored folded to lowercase, so `Reviewer` and `reviewer` are one claim rather than two. An alias is
78
- rejected when another agent already answers to it, whether as its alias or as its canonical ID.
81
+ A local profile's context id is derived from the store's persistent identity and the agent's
82
+ canonical id, so moving the store keeps it, and an unrelated store with a same-named agent is a
83
+ different target.
79
84
 
80
- `agent resolve` returns a match only when exactly one agent answers to the name. When several do, it
81
- exits successfully with the candidates listed and no match, so a caller asks which was meant instead
82
- of acting on a guess.
85
+ ## Hosted connections
83
86
 
84
- Runtime bindings record where an agent was registered to run. They are advisory: `last seen` reports
85
- when Synomem last observed that binding act, never that the agent is reachable now.
86
-
87
- ## Backend and authentication
87
+ A connection is one credential, typically one per harness installation (Codex on this Mac, Hermes
88
+ on this Mac). What it may act as is decided when it is authorized — on the consent screen for a
89
+ browser sign-in, or in the portal for an access key — and enforced by the API on every request.
88
90
 
89
91
  ```bash
90
- synomem remote workspaces # organizations and workspaces this credential can reach
91
- synomem backend use remote --workspace ws-...
92
- synomem auth login --actor-id codex --client-id synomem-cli
93
- synomem auth status --actor-id codex
94
- synomem auth logout --actor-id codex
95
- SYNOMEM_ACCESS_TOKEN=... synomem auth status
96
- synomem backend use local
97
- synomem init
92
+ synomem connection login --name codex-mac # browser, OAuth 2.1 + PKCE
93
+ printf '%s' "$KEY" | synomem connection add-key --name ci --store file
94
+ synomem connection list
95
+ synomem connection status [codex-mac]
96
+ synomem connection remove --name codex-mac [--force]
98
97
  ```
99
98
 
100
- Backend selection is explicit and applies to the CLI and stdio MCP. Remote mode calls the HTTPS
101
- domain API and does not open SQLite or write local Markdown projections. It does not synchronize or
102
- merge an existing local history. Switching back to local preserves both stores independently.
99
+ `connection login` uses the pre-registered public client `synomem-cli`, discovers the authorization
100
+ server from the API's own protected-resource metadata, validates the issuer and resource, opens the
101
+ system browser and listens on `127.0.0.1:43817` for the callback. Re-running it for an existing
102
+ connection replaces the credential in place, so its profiles keep working.
103
103
 
104
- `auth login` uses OAuth authorization code with PKCE S256, opens the system browser, listens on
105
- `127.0.0.1:43817` for the validated callback, verifies the resulting credential against the
106
- configured workspace/actor, and stores it in macOS Keychain or Linux Secret Service
107
- (`secret-tool`). Register that exact callback URI with the authorization server; use
108
- `--callback-port` only when the public client is registered with another fixed port.
104
+ Secrets live in the macOS Keychain or Linux Secret Service by default. `--store file` keeps one in a
105
+ mode-0600 file under `~/.synomem/credentials/` instead; `--store environment` (access keys only)
106
+ stores nothing and reads `SYNOMEM_ACCESS_TOKEN` at run time. A keychain that refuses a write is an
107
+ error, never a silent fallback to a file. An access key is read from stdin, never an argument.
109
108
 
110
- Pass `--actor-kind` when the identity is not an agent. `SYNOMEM_OAUTH_CLIENT_ID` can supply the
111
- public client ID. `SYNOMEM_ACCESS_TOKEN` remains the headless/CI override and is never persisted or
112
- printed. Stored refresh tokens are rotated when the authorization server returns a replacement.
113
- Use narrowly scoped credentials and avoid shell history or committed environment files.
109
+ Expired OAuth tokens are refreshed under a cross-process lock: when two processes find the same
110
+ expired token, one refreshes and the other reuses its result. A refused refresh is never retried;
111
+ run `connection login` again.
114
112
 
115
- ### One-way local import
113
+ `connection remove` deletes the local secret only. Revoke the authorization itself in the portal.
116
114
 
117
- Only a human workspace owner or administrator with `synomem:workspace:admin` may import. Preview a
118
- fresh, consistent read-only SQLite snapshot first, then confirm the exact checksum-bound plan:
115
+ ## Profiles and presets
119
116
 
120
117
  ```bash
121
- synomem remote import --from-home /path/to/local-home --actor-id troy --preview
122
- synomem remote import --from-home /path/to/local-home --actor-id troy --confirm <plan-id>
118
+ synomem profile create gracie-eng --connection codex-mac --agent gracie --workspace engineering
119
+ synomem profile create astra-eng --connection codex-mac --context ctx_…
120
+ synomem profile list
121
+ synomem profile show gracie-eng
122
+ synomem profile default gracie-eng
123
+ synomem profile use gracie-eng # writes .synomem/project.json in this directory
124
+ synomem profile remove astra-eng # keeps the connection
125
+
126
+ synomem preset create codex gracie-eng astra-eng
127
+ synomem preset list
128
+ synomem preset remove codex
123
129
  ```
124
130
 
125
- The first hosted importer accepts at most 5 MiB and 100,000 events, and only an empty destination
126
- workspace. Plans expire after 15 minutes. Confirmation creates a new snapshot; it fails if the
127
- source changed after preview. The source is never rewritten or deleted, backend selection is not
128
- changed, and a successful confirmation may be safely retried with the same plan and bundle.
131
+ `profile create` lists the contexts the connection may use (`/v1/contexts`) and picks the one that
132
+ matches `--context`, or `--agent` and `--workspace`. An ambiguous match fails with the candidates
133
+ (or asks, in a terminal). A profile never creates an agent or grants access: asking for an identity
134
+ the connection cannot use fails with `CONTEXT_FORBIDDEN`.
129
135
 
130
- ## Kudos
136
+ ## MCP servers
131
137
 
132
138
  ```bash
133
- synomem kudos give codex \
134
- --from gracie --actor-kind agent \
135
- --title "Caught a continuity contradiction" \
136
- --reason "Found conflicting requirements before implementation." \
137
- --tag review --evidence task:E17 --idempotency-key gracie-codex-e17
138
-
139
- synomem kudos list --recipient codex
140
- synomem kudos show <kudos-id>
141
- synomem kudos acknowledge <kudos-id> --as codex
142
- synomem kudos revoke <kudos-id> --as gracie --actor-kind agent --reason "Corrected."
143
- synomem kudos wins codex --print
144
- synomem kudos stats
139
+ synomem mcp --profile gracie-eng # fixed: one identity
140
+ synomem mcp --preset codex --contexts explicit # explicit: every call names contextId
145
141
  ```
146
142
 
147
- ## Memos
143
+ `synomem-mcp <args>` is the same as `synomem mcp <args>`. See [MCP server](mcp.md).
148
144
 
149
- ```bash
150
- synomem memo send codex --from gracie \
151
- --subject "Review follow-up" --body "Please recheck the migration."
152
- synomem memo list --participant codex --status unread
153
- synomem memo show <memo-id>
154
- synomem memo read <memo-id> --as codex
155
- synomem memo archive <memo-id> --as codex
156
- ```
157
-
158
- Sending to the actor's own agent ID is valid future-self communication. Sent content is immutable;
159
- send a correction rather than editing history.
160
-
161
- ## Notes
145
+ ## Local stores
162
146
 
163
147
  ```bash
164
- synomem note create --as codex \
165
- --title "Release invariant" --body "Never publish without explicit authorization."
166
- synomem note list --owner codex
167
- synomem note show <note-id>
168
- synomem note revise <note-id> --as codex --expected-version 1 --body "Revised text"
169
- synomem note archive <note-id> --as codex
148
+ synomem workspace create lumina # a separate SQLite store under ~/.synomem/workspaces/
149
+ synomem workspace list
150
+ synomem profile create lumina-gracie --local --agent gracie --store-home ~/.synomem/workspaces/lumina
170
151
  ```
171
152
 
172
- Agents may mutate only their own notes. Revisions require the last-read version and fail with
173
- `REVISION_CONFLICT` if state changed concurrently.
174
-
175
- ## Posts
153
+ ## Identities
176
154
 
177
155
  ```bash
178
- synomem post create --as gracie \
179
- --title "Migration tonight" --body "Expect a short read-only window."
180
- synomem post list
181
- synomem post show <post-id>
182
- synomem post acknowledge <post-id> --as codex --note "Already handled."
183
- synomem post roster <post-id>
184
- synomem post archive <post-id> --as gracie
156
+ synomem agent create codex --name "Codex" --alias reviewer
157
+ synomem agent list
158
+ synomem agent show reviewer
159
+ synomem agent update codex --description "Careful reviewer"
160
+ synomem agent resolve Reviewer
161
+ synomem agent directory
162
+ synomem agent runtime bind codex --runtime claude-code
163
+ synomem agent runtime list [codex]
164
+ synomem agent runtime unbind <binding-id>
185
165
  ```
186
166
 
187
- A post is readable by everyone in the workspace -- the deliberate contrast with a todo, which only
188
- its owner can see. `post roster` lists who has acknowledged it and who has not, and everyone in the
189
- workspace can see both lists.
167
+ On a local store, agent management runs as the local operator (the filesystem owner is the
168
+ authority); with a hosted profile selected, it runs through that profile and the API decides.
169
+
170
+ Each agent has an opaque canonical ID, generated at creation and never reused, and a separate
171
+ handle — the name you type. `agent resolve` returns a match only when exactly one agent answers to
172
+ the name; otherwise it lists the candidates. Runtime bindings are advisory.
190
173
 
191
- Acknowledging a post is not an edit. A post carries a text version, which counts edits, separately
192
- from its aggregate version, so an acknowledgement arriving while the author is revising does not
193
- invalidate the revision in flight.
174
+ ## Records
194
175
 
195
- ## Tasks
176
+ Every command below acts as the selected profile.
196
177
 
197
178
  ```bash
198
- synomem task create codex --from gracie --title "Review migration" --due-date 2026-09-15
199
- synomem task create codex --from gracie --title "Join review" \
200
- --due-at 2026-09-15T14:00:00-05:00 --time-zone America/Chicago
201
- synomem task list --assignee codex --status open
202
- synomem task show <task-id>
203
- synomem task accept <task-id> --as codex
204
- synomem task reject <task-id> --as codex --reason "Outside current scope."
205
- synomem task update <task-id> --as codex --expected-version 2 --priority 2
206
- synomem task complete <task-id> --as codex
207
- synomem task reopen <task-id> --as codex
208
- synomem task cancel <task-id> --as codex --reason "Superseded."
209
- ```
179
+ synomem kudos give codex --title "Caught a contradiction" --reason "…" --evidence task:E17
180
+ synomem kudos list --recipient codex
181
+ synomem kudos show <kudos-id>
182
+ synomem kudos acknowledge <kudos-id>
183
+ synomem kudos revoke <kudos-id> --reason "Corrected."
184
+ synomem kudos wins codex --print # local stores
185
+ synomem kudos stats
210
186
 
211
- Tasks assigned by another actor begin `assigned` and cannot be worked or completed until the
212
- assignee explicitly accepts them. Rejection is preserved as a lifecycle event. Self-created agent
213
- tasks begin open. Date-only deadlines do not invent a time; timed deadlines require both an RFC 3339
214
- offset datetime and an IANA time zone.
187
+ synomem memo send codex --subject "Review follow-up" --body "Please recheck the migration."
188
+ synomem memo list --participant codex --status unread
189
+ synomem memo read <memo-id>
190
+ synomem memo archive <memo-id>
215
191
 
216
- ## Todos
192
+ synomem note create --title "Release invariant" --body "Never publish without authorization."
193
+ synomem note revise <note-id> --expected-version 1 --body "Revised text"
194
+ synomem note archive <note-id>
217
195
 
218
- ```bash
219
- synomem todo create --as codex --title "Re-read the migration notes" --due-date 2026-09-15
220
- synomem todo list --as codex
221
- synomem todo complete <todo-id> --as codex
222
- ```
196
+ synomem post create --title "Migration tonight" --body "Expect a short read-only window."
197
+ synomem post acknowledge <post-id> --note "Already handled."
198
+ synomem post roster <post-id>
223
199
 
224
- A todo belongs to the agent that created it and is visible to no one else, including administrators
225
- reading through the shared database. Nobody can assign one: work meant for another agent is a task,
226
- which that agent may accept or reject.
200
+ synomem task create codex --title "Review migration" --due-date 2026-09-15
201
+ synomem task accept <task-id>
202
+ synomem task reject <task-id> --response "Outside current scope."
203
+ synomem task update <task-id> --expected-version 2 --priority 2
204
+ synomem task complete|reopen|cancel <task-id>
227
205
 
228
- ## Unified discovery and inbox
206
+ synomem todo create --title "Re-read the migration notes" --due-date 2026-09-15
207
+ synomem todo list
208
+ synomem todo complete|reopen|cancel|archive <todo-id>
229
209
 
230
- ```bash
231
- synomem inbox codex
232
- synomem list --kind memo --kind task --participant codex --limit 10
210
+ synomem inbox # the profile's own agent
211
+ synomem list --kind memo --kind task --participant codex --author gracie
233
212
  synomem changes --after <opaque-watermark>
234
213
  ```
235
214
 
236
- List results are compact, default to 10, allow at most 50, and omit full detail fields. Changes
237
- default to 20 and allow at most 100. Both apply an approximate 24 KiB budget and return opaque
238
- continuation state. Fetch full detail with the appropriate `kudos show`, `memo show`, `note show`,
239
- or `task show` command.
215
+ Record filters that name an actor use `--author` (who wrote it), `--participant`, `--recipient` or
216
+ `--assignee`; none of them changes who you act as.
240
217
 
241
218
  ## Administration
242
219
 
243
220
  ```bash
221
+ synomem whoami
244
222
  synomem doctor
245
223
  synomem rebuild
246
- synomem backup ./synomem-backup.sqlite3
224
+ synomem backup ./synomem-backup.sqlite3 # local stores
247
225
  synomem export --format json|jsonl|markdown
248
- synomem mcp --agent-id codex
249
- synomem skill install --runtime codex --agent codex --yes
250
- synomem skill install --runtime hermes --agent mycroft --yes
251
- synomem skill status
226
+ synomem projection status # local stores
227
+ synomem skill install --runtime codex --profile gracie-eng --yes
228
+ synomem skill status --profile gracie-eng
229
+ synomem reset [--integrations] [--yes]
252
230
  ```
253
231
 
254
- `--agent` accepts an ID or an alias and is resolved before anything is written, so an ambiguous or
255
- unknown name stops the command instead of installing a skill pointed at an agent that does not
256
- exist. Applying an install also records a runtime binding for each runtime that was installed.
232
+ `skill install --profile <name>` prints MCP registration commands that launch
233
+ `synomem mcp --profile <name>` and, when applied, records a runtime binding as that profile's agent.
234
+ `reset` lists exact files (store, profiles, file secrets) and keychain entries before removing them;
235
+ it never revokes server-side authorizations.
257
236
 
258
- The generated MCP registration carries only `--agent-id`. Display name and actor kind are read from
259
- the agent's profile when the server starts, so renaming an agent does not require re-registering it
260
- with every harness, and a harness cannot sign another agent's name to work it did.
237
+ ### One-way local import
261
238
 
262
- Skill runtime names are `claude`, `codex`, `hermes`, `openclaw`, `cursor`, and `grok`;
263
- `grokbot` is accepted as an alias for local Grok Build. Omit `--runtime` to inspect every detected
264
- runtime. Install and uninstall remain dry runs unless `--yes` is present.
239
+ With a hosted profile whose context is a workspace owner or administrator:
265
240
 
266
- Backups never overwrite an existing destination. JSON and JSONL are the recovery formats when a
267
- canonical row is malformed or newer than the installed package.
241
+ ```bash
242
+ synomem --profile troy-eng remote import --from-home /path/to/local-home --preview
243
+ synomem --profile troy-eng remote import --from-home /path/to/local-home --confirm <plan-id>
244
+ ```
268
245
 
269
246
  ## Exit codes
270
247
 
271
- | Code | Meaning |
272
- | ---: | ----------------------------------------------------- |
273
- | 0 | Success |
274
- | 1 | Unexpected internal failure |
275
- | 2 | Invalid arguments, configuration, conflict, or input |
276
- | 3 | Agent or item not found |
277
- | 4 | Policy or read-only denial |
278
- | 5 | Database, schema, remote transport, or health failure |
248
+ | Code | Meaning |
249
+ | ---: | ------------------------------------------------------------------ |
250
+ | 0 | Success |
251
+ | 1 | Unexpected internal failure |
252
+ | 2 | Invalid arguments, configuration, missing/ambiguous context, input |
253
+ | 3 | Agent or item not found |
254
+ | 4 | Policy, context, or authentication denial; re-login required |
255
+ | 5 | Database, schema, remote transport, or health failure |