mindsync-ai 1.1.0__tar.gz
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.
- mindsync_ai-1.1.0/LICENSE +21 -0
- mindsync_ai-1.1.0/PKG-INFO +248 -0
- mindsync_ai-1.1.0/README.md +215 -0
- mindsync_ai-1.1.0/mindsync/__init__.py +3 -0
- mindsync_ai-1.1.0/mindsync/bridge.py +516 -0
- mindsync_ai-1.1.0/mindsync/bus/__init__.py +16 -0
- mindsync_ai-1.1.0/mindsync/bus/events.py +187 -0
- mindsync_ai-1.1.0/mindsync/bus/models.py +147 -0
- mindsync_ai-1.1.0/mindsync/config.py +131 -0
- mindsync_ai-1.1.0/mindsync/conflict.py +117 -0
- mindsync_ai-1.1.0/mindsync/dispatch/__init__.py +19 -0
- mindsync_ai-1.1.0/mindsync/dispatch/__main__.py +4 -0
- mindsync_ai-1.1.0/mindsync/dispatch/adapters.py +149 -0
- mindsync_ai-1.1.0/mindsync/dispatch/cli.py +134 -0
- mindsync_ai-1.1.0/mindsync/dispatch/presets/aider.json +11 -0
- mindsync_ai-1.1.0/mindsync/dispatch/presets/claude.json +11 -0
- mindsync_ai-1.1.0/mindsync/dispatch/presets/codex.json +12 -0
- mindsync_ai-1.1.0/mindsync/dispatch/presets/cursor.json +11 -0
- mindsync_ai-1.1.0/mindsync/dispatch/presets/gemini.json +11 -0
- mindsync_ai-1.1.0/mindsync/dispatch/presets/grok.json +11 -0
- mindsync_ai-1.1.0/mindsync/dispatch/proc.py +271 -0
- mindsync_ai-1.1.0/mindsync/dispatch/runner.py +239 -0
- mindsync_ai-1.1.0/mindsync/dispatch/store.py +141 -0
- mindsync_ai-1.1.0/mindsync/server.py +715 -0
- mindsync_ai-1.1.0/mindsync/storage.py +440 -0
- mindsync_ai-1.1.0/mindsync_ai.egg-info/PKG-INFO +248 -0
- mindsync_ai-1.1.0/mindsync_ai.egg-info/SOURCES.txt +41 -0
- mindsync_ai-1.1.0/mindsync_ai.egg-info/dependency_links.txt +1 -0
- mindsync_ai-1.1.0/mindsync_ai.egg-info/entry_points.txt +3 -0
- mindsync_ai-1.1.0/mindsync_ai.egg-info/requires.txt +9 -0
- mindsync_ai-1.1.0/mindsync_ai.egg-info/top_level.txt +1 -0
- mindsync_ai-1.1.0/pyproject.toml +66 -0
- mindsync_ai-1.1.0/setup.cfg +4 -0
- mindsync_ai-1.1.0/tests/test_bridge_validation.py +307 -0
- mindsync_ai-1.1.0/tests/test_concurrency.py +166 -0
- mindsync_ai-1.1.0/tests/test_config.py +45 -0
- mindsync_ai-1.1.0/tests/test_conflict.py +148 -0
- mindsync_ai-1.1.0/tests/test_dispatch.py +249 -0
- mindsync_ai-1.1.0/tests/test_event_bus.py +190 -0
- mindsync_ai-1.1.0/tests/test_mcp_stdio.py +79 -0
- mindsync_ai-1.1.0/tests/test_remote_jsonl_migration.py +170 -0
- mindsync_ai-1.1.0/tests/test_server_sync.py +175 -0
- mindsync_ai-1.1.0/tests/test_storage.py +173 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MindSync contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mindsync-ai
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: MindSync AI — unified MCP server for multi-agent memory, event bus, and CLI agent dispatch
|
|
5
|
+
Author: Aditya Arya, MindSync Contributors
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/adityarya24/mindsync-mcp
|
|
8
|
+
Project-URL: Documentation, https://github.com/adityarya24/mindsync-mcp#readme
|
|
9
|
+
Project-URL: Issues, https://github.com/adityarya24/mindsync-mcp/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/adityarya24/mindsync-mcp/blob/master/CHANGELOG.md
|
|
11
|
+
Keywords: mcp,memory,sync,multi-agent,agents,llm,event-bus,dispatch,mindsync-ai
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: mcp<2,>=1.27.0
|
|
25
|
+
Requires-Dist: pydantic>=2.0
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
29
|
+
Requires-Dist: build; extra == "dev"
|
|
30
|
+
Requires-Dist: twine; extra == "dev"
|
|
31
|
+
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
# MindSync AI
|
|
35
|
+
|
|
36
|
+
[](https://github.com/adityarya24/mindsync-mcp/actions/workflows/ci.yml)
|
|
37
|
+
[](https://pypi.org/project/mindsync-ai/)
|
|
38
|
+
[](https://pypi.org/project/mindsync-ai/)
|
|
39
|
+
|
|
40
|
+
**One Python MCP server** for multi-agent teams: shared memory, focus conflict detection, an in-process event bus, and CLI agent dispatch (Codex, Claude, Gemini, Cursor, Aider, Grok).
|
|
41
|
+
|
|
42
|
+
| Layer | What it does |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| **Core** | Local-first focus registry + optional durable facts over SSH |
|
|
45
|
+
| **Bus** | Typed events (`job.*`, `focus.changed`, `memory.updated`, …) with monotonic `seq` |
|
|
46
|
+
| **Dispatch** | Spawn headless CLI agents, track jobs, cancel process trees |
|
|
47
|
+
|
|
48
|
+
No cloud account required. Remote sync is opt-in. Zero hard-coded hosts or personal paths.
|
|
49
|
+
|
|
50
|
+
> **Package rename (v1.1.0):** PyPI name is now **`mindsync-ai`** (was `mindsync-mcp` through 1.0.1).
|
|
51
|
+
> Import path and CLI stay the same: `import mindsync` · `mindsync`.
|
|
52
|
+
|
|
53
|
+
## Install
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install mindsync-ai
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Requires Python 3.10+.
|
|
60
|
+
|
|
61
|
+
From source:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
git clone https://github.com/adityarya24/mindsync-mcp.git
|
|
65
|
+
cd mindsync-mcp
|
|
66
|
+
python -m pip install -e ".[dev]"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## MCP client config
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"mcpServers": {
|
|
74
|
+
"mindsync": {
|
|
75
|
+
"command": "mindsync"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Or:
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"mcpServers": {
|
|
86
|
+
"mindsync": {
|
|
87
|
+
"command": "python",
|
|
88
|
+
"args": ["-m", "mindsync.server"]
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
(Windows: point at your venv’s `python.exe` if agents don’t share PATH.)
|
|
95
|
+
|
|
96
|
+
## Tools (13)
|
|
97
|
+
|
|
98
|
+
### Core memory / focus
|
|
99
|
+
|
|
100
|
+
| Tool | Purpose |
|
|
101
|
+
| --- | --- |
|
|
102
|
+
| `get_sync_context` | Local state + compiled truth (optional remote pull) |
|
|
103
|
+
| `update_focus` | Per-agent focus/project/branch/paths; conflict warnings → emits `focus.changed` |
|
|
104
|
+
| `queue_durable_fact` | Remote write or offline queue → emits `memory.updated` |
|
|
105
|
+
| `sync_offline_facts` | Flush offline queue; consolidate + pull truth |
|
|
106
|
+
| `pull_truth` | Windows-safe SCP pull of compiled-truth markdown |
|
|
107
|
+
| `health` | Paths, queue depth, remote reachability |
|
|
108
|
+
|
|
109
|
+
### Event bus
|
|
110
|
+
|
|
111
|
+
| Tool | Purpose |
|
|
112
|
+
| --- | --- |
|
|
113
|
+
| `publish_event` | Publish a typed event with payload |
|
|
114
|
+
| `poll_events` | Poll events since a sequence number |
|
|
115
|
+
| `subscribe_events` | Subscribe an agent to event types |
|
|
116
|
+
|
|
117
|
+
### Agent dispatch
|
|
118
|
+
|
|
119
|
+
| Tool | Purpose |
|
|
120
|
+
| --- | --- |
|
|
121
|
+
| `delegate_task` | Run a CLI agent (foreground or background) |
|
|
122
|
+
| `job_status` | Job status + PID reconciliation |
|
|
123
|
+
| `job_result` | Read job result file |
|
|
124
|
+
| `job_cancel` | Cancel running job and kill its process tree |
|
|
125
|
+
|
|
126
|
+
Dispatch also auto-emits `job.started`, `job.completed`, and `job.failed` on the bus.
|
|
127
|
+
|
|
128
|
+
### CLI (dispatch)
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
mindsync-dispatch agents
|
|
132
|
+
mindsync-dispatch run codex "summarize README" --background
|
|
133
|
+
mindsync-dispatch status
|
|
134
|
+
mindsync-dispatch result <job-id>
|
|
135
|
+
mindsync-dispatch cancel <job-id>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Jobs live under `~/.claude/agent-dispatch/jobs/` (override with `AGENT_DISPATCH_HOME`).
|
|
139
|
+
Custom agents: `~/.claude/agent-dispatch/agents.json`.
|
|
140
|
+
|
|
141
|
+
Built-in presets: `codex`, `claude`, `gemini`, `cursor`, `aider`, `grok`.
|
|
142
|
+
|
|
143
|
+
## Quick start (local only)
|
|
144
|
+
|
|
145
|
+
No env vars required for core + bus + dispatch. State lives under `~/.mindsync`.
|
|
146
|
+
|
|
147
|
+
1. **Start:** `get_sync_context(agent_name)`
|
|
148
|
+
2. **Work:** `update_focus(agent_name, project, branch, focus, paths=[...])`
|
|
149
|
+
3. **Milestone:** `queue_durable_fact(agent_name, entity, attribute, text)`
|
|
150
|
+
4. **Delegate:** `delegate_task(agent="codex", prompt="...", background=True)`
|
|
151
|
+
5. **Reconnect:** `sync_offline_facts(agent_name)` when remote is configured
|
|
152
|
+
|
|
153
|
+
## Optional remote sync
|
|
154
|
+
|
|
155
|
+
Remote stays **disabled** until both are set:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
export MINDSYNC_SSH_HOST=my-server # SSH config Host or user@host
|
|
159
|
+
export MINDSYNC_REMOTE_ROOT=/opt/mindsync # directory on that host
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
See [`.env.example`](.env.example) and [`examples/remote/`](examples/remote/).
|
|
163
|
+
|
|
164
|
+
| Env var | Default | Meaning |
|
|
165
|
+
| --- | --- | --- |
|
|
166
|
+
| `MINDSYNC_HOME` | `~/.mindsync` | Local data root |
|
|
167
|
+
| `MINDSYNC_SSH_HOST` | *(empty)* | SSH host; empty disables remote |
|
|
168
|
+
| `MINDSYNC_REMOTE_ROOT` | *(empty)* | Remote project root |
|
|
169
|
+
| `MINDSYNC_REMOTE_ENV_FILE` | `config/mindsync.env` | Sourced on remote before commands |
|
|
170
|
+
| `MINDSYNC_REMOTE_WRITE_SCRIPT` | `tools/mindsync_fact.py` | Relative to remote root |
|
|
171
|
+
| `MINDSYNC_REMOTE_CONSOLIDATE_SCRIPT` | `tools/mindsync_consolidate.py` | Relative to remote root |
|
|
172
|
+
| `MINDSYNC_REMOTE_TRUTH_SUBDIR` | `compiled-truth` | Markdown summaries directory |
|
|
173
|
+
| `MINDSYNC_SSH_TIMEOUT` | `3` | SSH connect timeout (seconds) |
|
|
174
|
+
| `MINDSYNC_FOCUS_STALE_SECS` | `7200` | Ignore older focus entries |
|
|
175
|
+
| `MINDSYNC_REMOTE_CACHE_TTL` | `30` | Cache TTL for online probe |
|
|
176
|
+
| `MINDSYNC_LOCK_TIMEOUT` | `5` | Local lock wait (seconds) |
|
|
177
|
+
| `MINDSYNC_LOCK_STALE_SECS` | `60` | Steal lock after holder stops renewing |
|
|
178
|
+
|
|
179
|
+
SSH must be key-based / `BatchMode`-friendly.
|
|
180
|
+
|
|
181
|
+
### Two machines (VPS + laptop)
|
|
182
|
+
|
|
183
|
+
Run MindSync AI on **each** machine for local focus/state. Share **durable facts** via one always-on host:
|
|
184
|
+
|
|
185
|
+
1. **VPS:** deploy [`examples/remote/`](examples/remote/) scripts under e.g. `/opt/mindsync`.
|
|
186
|
+
2. **Laptop:** set `MINDSYNC_SSH_HOST` + `MINDSYNC_REMOTE_ROOT` to that VPS.
|
|
187
|
+
3. **VPS itself:** leave remote vars empty — it *is* the store.
|
|
188
|
+
|
|
189
|
+
## Local data layout
|
|
190
|
+
|
|
191
|
+
Under `MINDSYNC_HOME` (default `~/.mindsync`):
|
|
192
|
+
|
|
193
|
+
- `local-state.json` — active project + per-agent focus map
|
|
194
|
+
- `local-audit.jsonl` — append-only action log
|
|
195
|
+
- `offline_queue.jsonl` — durable facts waiting for remote
|
|
196
|
+
- `events.jsonl` — event bus log
|
|
197
|
+
- `subscriptions.json` — event subscriptions
|
|
198
|
+
- `compiled-truth/*.md` — pulled remote summaries
|
|
199
|
+
- `.locks/` — exclusive lockfiles
|
|
200
|
+
|
|
201
|
+
## Layout
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
mindsync-mcp/ # GitHub repo
|
|
205
|
+
├── mindsync/
|
|
206
|
+
│ ├── server.py # FastMCP tools (core + bus + dispatch)
|
|
207
|
+
│ ├── storage.py # JSON/JSONL + locks
|
|
208
|
+
│ ├── bridge.py # optional SSH/SCP
|
|
209
|
+
│ ├── conflict.py # focus overlap
|
|
210
|
+
│ ├── config.py # env-based settings
|
|
211
|
+
│ ├── bus/ # Event bus engine
|
|
212
|
+
│ └── dispatch/ # Agent dispatch (presets, runner, CLI)
|
|
213
|
+
├── examples/remote/
|
|
214
|
+
├── tests/
|
|
215
|
+
└── pyproject.toml # PyPI: mindsync-ai
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Develop / test
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
python -m pip install -e ".[dev]"
|
|
222
|
+
python -m pytest -q
|
|
223
|
+
python scripts/smoke_test.py
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
CI runs on every push/PR to `master` (Python 3.10 / 3.12 / 3.13 × Ubuntu + Windows).
|
|
227
|
+
|
|
228
|
+
## Design principles
|
|
229
|
+
|
|
230
|
+
1. **Offline-first** — local tools always work; remote is opt-in.
|
|
231
|
+
2. **Locked local state** — exclusive locks around state/queue/events.
|
|
232
|
+
3. **Safe remote writes** — identifier allowlists + base64 text over SSH.
|
|
233
|
+
4. **No false-positive conflicts** — same project alone is not a conflict.
|
|
234
|
+
5. **Generic by default** — zero personal paths in code.
|
|
235
|
+
6. **Safe dispatch** — model tokens validated; Windows `.cmd`/`.bat` arg-mode prompts blocked.
|
|
236
|
+
|
|
237
|
+
## Security notes
|
|
238
|
+
|
|
239
|
+
- Runs with the privileges of the executing user. Wire only into trusted local agents.
|
|
240
|
+
- Pulled remote truth is treated as untrusted (filename/UTF-8 validation, atomic swap).
|
|
241
|
+
- Local store defaults to Unix `0700` dirs / `0600` files where the OS allows.
|
|
242
|
+
- SSH errors are scrubbed before return to clients.
|
|
243
|
+
|
|
244
|
+
Full details: [`SECURITY.md`](SECURITY.md).
|
|
245
|
+
|
|
246
|
+
## License
|
|
247
|
+
|
|
248
|
+
MIT
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# MindSync AI
|
|
2
|
+
|
|
3
|
+
[](https://github.com/adityarya24/mindsync-mcp/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/mindsync-ai/)
|
|
5
|
+
[](https://pypi.org/project/mindsync-ai/)
|
|
6
|
+
|
|
7
|
+
**One Python MCP server** for multi-agent teams: shared memory, focus conflict detection, an in-process event bus, and CLI agent dispatch (Codex, Claude, Gemini, Cursor, Aider, Grok).
|
|
8
|
+
|
|
9
|
+
| Layer | What it does |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| **Core** | Local-first focus registry + optional durable facts over SSH |
|
|
12
|
+
| **Bus** | Typed events (`job.*`, `focus.changed`, `memory.updated`, …) with monotonic `seq` |
|
|
13
|
+
| **Dispatch** | Spawn headless CLI agents, track jobs, cancel process trees |
|
|
14
|
+
|
|
15
|
+
No cloud account required. Remote sync is opt-in. Zero hard-coded hosts or personal paths.
|
|
16
|
+
|
|
17
|
+
> **Package rename (v1.1.0):** PyPI name is now **`mindsync-ai`** (was `mindsync-mcp` through 1.0.1).
|
|
18
|
+
> Import path and CLI stay the same: `import mindsync` · `mindsync`.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install mindsync-ai
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Requires Python 3.10+.
|
|
27
|
+
|
|
28
|
+
From source:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
git clone https://github.com/adityarya24/mindsync-mcp.git
|
|
32
|
+
cd mindsync-mcp
|
|
33
|
+
python -m pip install -e ".[dev]"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## MCP client config
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"mcpServers": {
|
|
41
|
+
"mindsync": {
|
|
42
|
+
"command": "mindsync"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Or:
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"mcpServers": {
|
|
53
|
+
"mindsync": {
|
|
54
|
+
"command": "python",
|
|
55
|
+
"args": ["-m", "mindsync.server"]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
(Windows: point at your venv’s `python.exe` if agents don’t share PATH.)
|
|
62
|
+
|
|
63
|
+
## Tools (13)
|
|
64
|
+
|
|
65
|
+
### Core memory / focus
|
|
66
|
+
|
|
67
|
+
| Tool | Purpose |
|
|
68
|
+
| --- | --- |
|
|
69
|
+
| `get_sync_context` | Local state + compiled truth (optional remote pull) |
|
|
70
|
+
| `update_focus` | Per-agent focus/project/branch/paths; conflict warnings → emits `focus.changed` |
|
|
71
|
+
| `queue_durable_fact` | Remote write or offline queue → emits `memory.updated` |
|
|
72
|
+
| `sync_offline_facts` | Flush offline queue; consolidate + pull truth |
|
|
73
|
+
| `pull_truth` | Windows-safe SCP pull of compiled-truth markdown |
|
|
74
|
+
| `health` | Paths, queue depth, remote reachability |
|
|
75
|
+
|
|
76
|
+
### Event bus
|
|
77
|
+
|
|
78
|
+
| Tool | Purpose |
|
|
79
|
+
| --- | --- |
|
|
80
|
+
| `publish_event` | Publish a typed event with payload |
|
|
81
|
+
| `poll_events` | Poll events since a sequence number |
|
|
82
|
+
| `subscribe_events` | Subscribe an agent to event types |
|
|
83
|
+
|
|
84
|
+
### Agent dispatch
|
|
85
|
+
|
|
86
|
+
| Tool | Purpose |
|
|
87
|
+
| --- | --- |
|
|
88
|
+
| `delegate_task` | Run a CLI agent (foreground or background) |
|
|
89
|
+
| `job_status` | Job status + PID reconciliation |
|
|
90
|
+
| `job_result` | Read job result file |
|
|
91
|
+
| `job_cancel` | Cancel running job and kill its process tree |
|
|
92
|
+
|
|
93
|
+
Dispatch also auto-emits `job.started`, `job.completed`, and `job.failed` on the bus.
|
|
94
|
+
|
|
95
|
+
### CLI (dispatch)
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
mindsync-dispatch agents
|
|
99
|
+
mindsync-dispatch run codex "summarize README" --background
|
|
100
|
+
mindsync-dispatch status
|
|
101
|
+
mindsync-dispatch result <job-id>
|
|
102
|
+
mindsync-dispatch cancel <job-id>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Jobs live under `~/.claude/agent-dispatch/jobs/` (override with `AGENT_DISPATCH_HOME`).
|
|
106
|
+
Custom agents: `~/.claude/agent-dispatch/agents.json`.
|
|
107
|
+
|
|
108
|
+
Built-in presets: `codex`, `claude`, `gemini`, `cursor`, `aider`, `grok`.
|
|
109
|
+
|
|
110
|
+
## Quick start (local only)
|
|
111
|
+
|
|
112
|
+
No env vars required for core + bus + dispatch. State lives under `~/.mindsync`.
|
|
113
|
+
|
|
114
|
+
1. **Start:** `get_sync_context(agent_name)`
|
|
115
|
+
2. **Work:** `update_focus(agent_name, project, branch, focus, paths=[...])`
|
|
116
|
+
3. **Milestone:** `queue_durable_fact(agent_name, entity, attribute, text)`
|
|
117
|
+
4. **Delegate:** `delegate_task(agent="codex", prompt="...", background=True)`
|
|
118
|
+
5. **Reconnect:** `sync_offline_facts(agent_name)` when remote is configured
|
|
119
|
+
|
|
120
|
+
## Optional remote sync
|
|
121
|
+
|
|
122
|
+
Remote stays **disabled** until both are set:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
export MINDSYNC_SSH_HOST=my-server # SSH config Host or user@host
|
|
126
|
+
export MINDSYNC_REMOTE_ROOT=/opt/mindsync # directory on that host
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
See [`.env.example`](.env.example) and [`examples/remote/`](examples/remote/).
|
|
130
|
+
|
|
131
|
+
| Env var | Default | Meaning |
|
|
132
|
+
| --- | --- | --- |
|
|
133
|
+
| `MINDSYNC_HOME` | `~/.mindsync` | Local data root |
|
|
134
|
+
| `MINDSYNC_SSH_HOST` | *(empty)* | SSH host; empty disables remote |
|
|
135
|
+
| `MINDSYNC_REMOTE_ROOT` | *(empty)* | Remote project root |
|
|
136
|
+
| `MINDSYNC_REMOTE_ENV_FILE` | `config/mindsync.env` | Sourced on remote before commands |
|
|
137
|
+
| `MINDSYNC_REMOTE_WRITE_SCRIPT` | `tools/mindsync_fact.py` | Relative to remote root |
|
|
138
|
+
| `MINDSYNC_REMOTE_CONSOLIDATE_SCRIPT` | `tools/mindsync_consolidate.py` | Relative to remote root |
|
|
139
|
+
| `MINDSYNC_REMOTE_TRUTH_SUBDIR` | `compiled-truth` | Markdown summaries directory |
|
|
140
|
+
| `MINDSYNC_SSH_TIMEOUT` | `3` | SSH connect timeout (seconds) |
|
|
141
|
+
| `MINDSYNC_FOCUS_STALE_SECS` | `7200` | Ignore older focus entries |
|
|
142
|
+
| `MINDSYNC_REMOTE_CACHE_TTL` | `30` | Cache TTL for online probe |
|
|
143
|
+
| `MINDSYNC_LOCK_TIMEOUT` | `5` | Local lock wait (seconds) |
|
|
144
|
+
| `MINDSYNC_LOCK_STALE_SECS` | `60` | Steal lock after holder stops renewing |
|
|
145
|
+
|
|
146
|
+
SSH must be key-based / `BatchMode`-friendly.
|
|
147
|
+
|
|
148
|
+
### Two machines (VPS + laptop)
|
|
149
|
+
|
|
150
|
+
Run MindSync AI on **each** machine for local focus/state. Share **durable facts** via one always-on host:
|
|
151
|
+
|
|
152
|
+
1. **VPS:** deploy [`examples/remote/`](examples/remote/) scripts under e.g. `/opt/mindsync`.
|
|
153
|
+
2. **Laptop:** set `MINDSYNC_SSH_HOST` + `MINDSYNC_REMOTE_ROOT` to that VPS.
|
|
154
|
+
3. **VPS itself:** leave remote vars empty — it *is* the store.
|
|
155
|
+
|
|
156
|
+
## Local data layout
|
|
157
|
+
|
|
158
|
+
Under `MINDSYNC_HOME` (default `~/.mindsync`):
|
|
159
|
+
|
|
160
|
+
- `local-state.json` — active project + per-agent focus map
|
|
161
|
+
- `local-audit.jsonl` — append-only action log
|
|
162
|
+
- `offline_queue.jsonl` — durable facts waiting for remote
|
|
163
|
+
- `events.jsonl` — event bus log
|
|
164
|
+
- `subscriptions.json` — event subscriptions
|
|
165
|
+
- `compiled-truth/*.md` — pulled remote summaries
|
|
166
|
+
- `.locks/` — exclusive lockfiles
|
|
167
|
+
|
|
168
|
+
## Layout
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
mindsync-mcp/ # GitHub repo
|
|
172
|
+
├── mindsync/
|
|
173
|
+
│ ├── server.py # FastMCP tools (core + bus + dispatch)
|
|
174
|
+
│ ├── storage.py # JSON/JSONL + locks
|
|
175
|
+
│ ├── bridge.py # optional SSH/SCP
|
|
176
|
+
│ ├── conflict.py # focus overlap
|
|
177
|
+
│ ├── config.py # env-based settings
|
|
178
|
+
│ ├── bus/ # Event bus engine
|
|
179
|
+
│ └── dispatch/ # Agent dispatch (presets, runner, CLI)
|
|
180
|
+
├── examples/remote/
|
|
181
|
+
├── tests/
|
|
182
|
+
└── pyproject.toml # PyPI: mindsync-ai
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Develop / test
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
python -m pip install -e ".[dev]"
|
|
189
|
+
python -m pytest -q
|
|
190
|
+
python scripts/smoke_test.py
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
CI runs on every push/PR to `master` (Python 3.10 / 3.12 / 3.13 × Ubuntu + Windows).
|
|
194
|
+
|
|
195
|
+
## Design principles
|
|
196
|
+
|
|
197
|
+
1. **Offline-first** — local tools always work; remote is opt-in.
|
|
198
|
+
2. **Locked local state** — exclusive locks around state/queue/events.
|
|
199
|
+
3. **Safe remote writes** — identifier allowlists + base64 text over SSH.
|
|
200
|
+
4. **No false-positive conflicts** — same project alone is not a conflict.
|
|
201
|
+
5. **Generic by default** — zero personal paths in code.
|
|
202
|
+
6. **Safe dispatch** — model tokens validated; Windows `.cmd`/`.bat` arg-mode prompts blocked.
|
|
203
|
+
|
|
204
|
+
## Security notes
|
|
205
|
+
|
|
206
|
+
- Runs with the privileges of the executing user. Wire only into trusted local agents.
|
|
207
|
+
- Pulled remote truth is treated as untrusted (filename/UTF-8 validation, atomic swap).
|
|
208
|
+
- Local store defaults to Unix `0700` dirs / `0600` files where the OS allows.
|
|
209
|
+
- SSH errors are scrubbed before return to clients.
|
|
210
|
+
|
|
211
|
+
Full details: [`SECURITY.md`](SECURITY.md).
|
|
212
|
+
|
|
213
|
+
## License
|
|
214
|
+
|
|
215
|
+
MIT
|