parallelclaw 1.0.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 (62) hide show
  1. package/CHANGELOG.md +204 -0
  2. package/HELP.md +600 -0
  3. package/LICENSE +21 -0
  4. package/MULTI_MACHINE.md +152 -0
  5. package/README.md +417 -0
  6. package/README.ru.md +740 -0
  7. package/SYNC.md +844 -0
  8. package/bot/README.md +173 -0
  9. package/bot/config.js +66 -0
  10. package/bot/inbox.js +153 -0
  11. package/bot/index.js +294 -0
  12. package/bot/nexara.js +61 -0
  13. package/bot/poll.js +304 -0
  14. package/bot/search.js +155 -0
  15. package/bot/telegram.js +96 -0
  16. package/ingest.js +2712 -0
  17. package/lib/cli/index.js +1987 -0
  18. package/lib/config.js +220 -0
  19. package/lib/db-init.js +158 -0
  20. package/lib/hook/install.js +268 -0
  21. package/lib/import-telegram.js +158 -0
  22. package/lib/ingest-file.js +779 -0
  23. package/lib/notify-click-action.js +281 -0
  24. package/lib/openclaw-channel.js +643 -0
  25. package/lib/parse-cursor.js +172 -0
  26. package/lib/parse-obsidian.js +256 -0
  27. package/lib/parse-telegram-html.js +384 -0
  28. package/lib/parse.js +175 -0
  29. package/lib/render-markdown.js +0 -0
  30. package/lib/store-doc/canonicalize.js +116 -0
  31. package/lib/store-doc/detect.js +209 -0
  32. package/lib/store-doc/extract-title.js +162 -0
  33. package/lib/sync/auth.js +80 -0
  34. package/lib/sync/cert.js +144 -0
  35. package/lib/sync/cli.js +906 -0
  36. package/lib/sync/client.js +138 -0
  37. package/lib/sync/config.js +130 -0
  38. package/lib/sync/pair.js +145 -0
  39. package/lib/sync/pull.js +158 -0
  40. package/lib/sync/push.js +305 -0
  41. package/lib/sync/replicate.js +335 -0
  42. package/lib/sync/server.js +224 -0
  43. package/lib/sync/service.js +726 -0
  44. package/lib/tasks.js +215 -0
  45. package/lib/telegram-decisions.js +165 -0
  46. package/lib/telegram-discovery.js +373 -0
  47. package/lib/telegram-notify.js +272 -0
  48. package/lib/telegram-pending.js +200 -0
  49. package/lib/web/index.js +265 -0
  50. package/lib/web/routes/conversation.js +193 -0
  51. package/lib/web/routes/conversations.js +180 -0
  52. package/lib/web/routes/dashboard.js +175 -0
  53. package/lib/web/routes/pending.js +277 -0
  54. package/lib/web/routes/settings.js +226 -0
  55. package/lib/web/static/style.css +393 -0
  56. package/lib/web/templates.js +234 -0
  57. package/package.json +84 -0
  58. package/server.js +3816 -0
  59. package/skills/install-memex/README.md +109 -0
  60. package/skills/install-memex/SKILL.md +342 -0
  61. package/skills/install-memex/examples.md +294 -0
  62. package/skills/install-memex-claw/SKILL.md +423 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,204 @@
1
+ # Changelog
2
+
3
+ Notable changes to parallelclaw (formerly memex-mvp). Older history lives in the git log.
4
+
5
+ ## 1.0.0 — rebrand: memex → ParallelClaw
6
+
7
+ The product is renamed **ParallelClaw** and repositioned from "AI memory" to a
8
+ **personal AI ops layer**: shared verbatim memory is the foundation, and a
9
+ coordination layer — any of your agents delegates a task to any other, across
10
+ tools and machines — is the direction. No users yet = the cheapest moment to fix
11
+ the name before building coordination under it.
12
+
13
+ This release renames the **surface** only; the **plumbing stays** as back-compat
14
+ aliases, so the live sync mesh and every existing install keep working untouched.
15
+
16
+ ### Changed
17
+ - **npm package `memex-mvp` → `parallelclaw`.** New bins `parallelclaw` + `pclaw`
18
+ (aliases of `server.js` — the query CLI / MCP server). `--version` now prints
19
+ the package name. Install is now `npm install -g parallelclaw`.
20
+ - **READMEs / landing / HELP / SYNC / skills / installers** rebranded to
21
+ ParallelClaw, plus a coordination **vision section** on the landing and READMEs
22
+ (no vaporware: memory ships today; the turnkey delegation loop is rolling out).
23
+
24
+ ### Kept as-is (back-compat — must NOT break the live mesh)
25
+ - Legacy bins `memex` / `memex-sync` / `memex-ingest` / `memex-bot` (docs still
26
+ use `memex …` / `memex-sync …` verbatim).
27
+ - Data dir `~/.memex`, DB `memex.db`, env vars `MEMEX_*`.
28
+ - launchd/systemd labels `com.parallelclaw.memex.*`.
29
+ - MCP tool names `memex_*`.
30
+ - GitHub repo path `parallelclaw/memex-mvp` and `git clone` dirs (repo rename
31
+ pending — a separate, out-of-band step; URLs unchanged for now).
32
+
33
+ ## 0.14.1 — patch: schema migration at sync-server boot
34
+
35
+ Upgrading a hub by `npm install -g` alone (no daemon/MCP boot in between) and
36
+ restarting the sync-server crash-looped it: the pull handler prepares a SELECT
37
+ over the new `origin` column at startup, against a not-yet-migrated DB.
38
+ `startSyncServer` now runs `initializeDb` before opening its handle. Found
39
+ live during the 0.14.0 rollout.
40
+
41
+ ## 0.14.0 — provenance: know which machine captured every row
42
+
43
+ In a synced mesh, all nodes' captures share the same `source` labels — two
44
+ OpenClaw instances both write `source='openclaw'`, and when they bridge the
45
+ same Telegram account they even interleave into ONE conversation. Two agents
46
+ in a row misread their own synced DB because of this (one invented a
47
+ nonexistent `source='vps1'` to look for — telling). v0.14 stamps every row
48
+ with the node that captured it.
49
+
50
+ ### Added
51
+ - **`origin` column on messages** — stamped at capture time on every local
52
+ write path (capture daemon, MCP imports, Telegram import, store_document,
53
+ sync self-test, OpenClaw plugin). Value resolution: `MEMEX_ORIGIN` env →
54
+ `origin` in `~/.memex/config.json` → sanitised short hostname, which is
55
+ then **persisted** so a later hostname change doesn't fork the node's
56
+ identity. Rename your node by editing `origin` in config.json.
57
+ - **Wire carries provenance** — sync pull/push move `origin` verbatim in both
58
+ directions; a synced row keeps the origin of the node that captured it,
59
+ never the receiver's. Old peers interoperate (unknown field ignored;
60
+ their rows arrive as NULL = "pre-provenance era").
61
+ - **`memex_search(origin: "vps1")`** — filter recall by capture node.
62
+ - **`memex_get_conversation`** tags each line `[@origin]` when a conversation
63
+ interleaves rows from more than one node (the merged-Telegram-chat case);
64
+ single-origin chats stay untagged. JSON format always includes `origin`.
65
+ - **`memex_overview`** shows a per-origin breakdown when the corpus is
66
+ multi-node.
67
+
68
+ ### Notes
69
+ - No blind backfill: a node cannot tell its own pre-v0.14 rows from peer rows
70
+ that synced in before provenance existed, and fabricating provenance is
71
+ worse than NULL. Re-imports of local source files DO backfill origin via
72
+ the conflict branch (`COALESCE(existing, incoming)` — never overwrites).
73
+ - The OpenClaw plugin (`plugins/memex-openclaw`) ships separately from the
74
+ npm package — update it on agent nodes to start stamping there.
75
+
76
+ ## 0.13.0 — `sync-join`: cross-device memory in two copy-paste steps
77
+
78
+ Multi-device sync goes from "for operators" to "for lazy users". Laptop with
79
+ Claude/Cursor + a server with an agent: the agent runs three commands and
80
+ hands you a `memex-join:` token; you paste **one command** on the laptop.
81
+ Dogfooded end-to-end by migrating the maintainer's own live mesh — every step
82
+ below shipped only after surviving that.
83
+
84
+ ### Added
85
+ - **`memex-sync sync-join <memex-join:...>`** — one-command spoke setup:
86
+ token validation → SSH probe (prints your pubkey + exact instructions if
87
+ access is missing) → durable forward tunnel (launchd KeepAlive / systemd
88
+ Restart=always; `ExitOnForwardFailure`, `ServerAlive 30×3`, explicit IPv4
89
+ loopback) → pinned-cert health check → remote registration → first sync →
90
+ 15-min auto-sync schedule → hourly watchdog → **marker self-test** that
91
+ proves a note round-trips before declaring success (`✓ end-to-end verified:
92
+ … 3.4s` on the live pair). Flags: `--alias`, `--local-port`, `--every`,
93
+ `--no-watchdog`, `--no-selftest`.
94
+ - **`memex-sync sync-server invite --join [--ssh-target u@h]`** — hub-side
95
+ join-token emission (`memex-join:` = pair blob + `ssh_target`, host pinned
96
+ to 127.0.0.1, TTL 30m). The server stays loopback-only; nothing is ever
97
+ exposed publicly — all traffic rides inside SSH on port 22.
98
+ - **`memex-sync sync-watchdog`** — read-only hourly health pass (installed by
99
+ join): remotes' `last_sync_at` freshness + tunnel unit state; on silence
100
+ writes `~/.memex/sync-alert.txt` + desktop notification. The "tunnel died
101
+ silently for 6 days" failure mode, productized away.
102
+ - **`sync-status`** now reports the tunnel keeper (route, self-healing state)
103
+ and watchdog alongside server/schedule/remotes.
104
+
105
+ ### Changed
106
+ - **No env var after joining** — a successful `sync-join` persists
107
+ `sync.enabled: true`; every sync command then works in any shell without
108
+ `MEMEX_SYNC_EXPERIMENTAL=1`.
109
+ - **Replication is resumable** — cursors persist after every clean pull page
110
+ and push batch, so an interrupted first sync (network reset, sleep, Ctrl-C)
111
+ resumes instead of restarting from zero; transient network errors
112
+ (ECONNRESET/EPIPE/ETIMEDOUT/ECONNREFUSED) retry in place with backoff tuned
113
+ to the tunnel's ~15s self-heal.
114
+ - **Re-joining a known hub keeps cursors** — if the token's cert fingerprint
115
+ matches the existing remote's, sync-join preserves cursor state instead of
116
+ forcing a full re-replication of an already-converged pair.
117
+ - **Docs lead with the lazy flow** — landing page, README (EN/RU), SYNC.md
118
+ quickstart, HELP.md section, MULTI_MACHINE.md legacy patterns marked
119
+ deprecated.
120
+
121
+ ### Fixed
122
+ - Tunnel-keeper script generation emitted a broken line continuation (`\ \`)
123
+ when no SSH identity file was configured — ssh received a stray empty
124
+ argument and the tunnel flapped forever. Regression-tested, including
125
+ backslash hygiene of every continuation line.
126
+
127
+ ## 0.12.0 — agent retrieval: reach any part of memory
128
+
129
+ Sharper recall for agents querying memex — especially across long sessions and
130
+ narrow time windows. Backward-compatible: every new parameter is optional and
131
+ defaults to the previous behaviour.
132
+
133
+ ### Added
134
+ - **`memex_get_conversation` paging** — new `offset` and `order` (`asc`|`desc`)
135
+ parameters, plus a `total` count in the output. A long session (e.g. 3000
136
+ messages) can now return its **freshest** tail (`order:"desc"`) or be paged
137
+ end-to-end — previously only the first ~N (oldest) were reachable. Fixes a real
138
+ gap found live: an agent could not show the June messages of a 2900-message
139
+ Claude Code session.
140
+ - **`memex_search` date-range filter** — `since_ts` / `until_ts` (Unix seconds,
141
+ inclusive) restrict results to a window ("what did we discuss about X in June").
142
+ A true filter, distinct from `sort` (orders only) and `half_life_days` (boosts
143
+ only). Numeric bounds naturally exclude undated rows.
144
+ - **`memex_search` within-conversation scope** — `conversation_id` confines a
145
+ keyword search to ONE session (exact id, unlike the fuzzy `chat` title match).
146
+ Pair it with `memex_get_conversation` paging to locate, then read around a hit
147
+ in a huge session.
148
+ - **Retrieval recipes** baked into the tool descriptions and `HELP.md` (new
149
+ "Рецепты поиска для агентов" table) so agents discover these paths without
150
+ guessing — date window, within-session search, freshest-first, page-a-giant.
151
+
152
+ ### Fixed
153
+ - **`memex_get_conversation` no longer hides the tail of long conversations** —
154
+ the handler always sorted `ts ASC LIMIT N` with no offset, so the newest
155
+ messages of any session past the limit were unreachable.
156
+ - **`test/sync/mcp-invite.test.js` is now hermetic** — the liveness-warning
157
+ assertion used a hard-coded port and failed on hosts that actually run a
158
+ sync-server on 8766; it now probes a guaranteed-closed port.
159
+
160
+ ## 0.11.11 — experimental multi-device sync
161
+
162
+ First cut of **local-first, multi-device sync** — converge two machines'
163
+ `memex.db` over the network with no cloud relay. Gated behind
164
+ `MEMEX_SYNC_EXPERIMENTAL=1`; the wire protocol may change before it graduates
165
+ to stable. Full guide + spec in [SYNC.md](SYNC.md).
166
+
167
+ ### Added
168
+ - **Sync engine** — HTTP push/pull + per-peer cursors. Conflict-free via the
169
+ existing `UNIQUE(source, conversation_id, msg_id)` constraint (verbatim memory
170
+ is append-only — nothing to merge). TLS with self-signed cert + **fingerprint
171
+ pinning**, 256-bit bearer auth.
172
+ - **CLI** (`memex-sync sync-*`):
173
+ - `sync-server start | install | uninstall | status` — run the hub, optionally
174
+ as a durable systemd-user / LaunchAgent service that survives reboot.
175
+ - `sync-server invite [--host H] [--port N] [--ttl 30]` — print a one-paste
176
+ `memex-pair:` token (bundles host + port + cert fingerprint + bearer, with TTL).
177
+ - `sync-pair <blob> [--alias vps]` — register a remote from a pair token.
178
+ - `sync-add <alias> <url> <bearer> (--cert-fp F | --insecure)` — explicit form.
179
+ - `sync-run <alias> | --all` — one bidirectional sync.
180
+ - `sync-schedule install [--every 15m] | uninstall | status` — hands-off
181
+ auto-sync on a timer.
182
+ - `sync-list / sync-remove / sync-status`.
183
+ - **`memex_sync_invite` MCP tool** — lets an agent emit a pairing token from a
184
+ plain-language request ("set up sync with my Mac"). Surfaced only when
185
+ `MEMEX_SYNC_EXPERIMENTAL=1` is set in the MCP server's environment.
186
+
187
+ ### Reliability
188
+ - **Adaptive push batching** — pre-flights payload size and shrinks before the
189
+ 2 MB body cap; backstops 413 / EPIPE by halving and retrying.
190
+ - **No silent row loss** — pulled rows are applied with retry; on the FTS5
191
+ "database disk image is malformed" error the index is rebuilt once and the
192
+ batch retried; if rows still won't apply, sync aborts **without advancing the
193
+ cursor** (loud failure over silent loss). Skips are counted and surfaced.
194
+ - **busy_timeout** on the sync connection to ride out the capture daemon's
195
+ concurrent writes.
196
+
197
+ ### Verified live
198
+ - Bidirectional Mac ↔ VPS sync over the public internet (32k+ rows each side,
199
+ cert-pinned), durable-server restart with credentials preserved, hands-off
200
+ auto-sync of a fresh conversation within one interval, and the full
201
+ agent-chat-phrase → pair-token → sync wow-flow.
202
+
203
+ ### Dependencies
204
+ - Added `selfsigned` (self-signed TLS cert generation for the sync server).