brainplug 0.4.0__py3-none-any.whl
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.
- brainplug/__init__.py +3 -0
- brainplug/__main__.py +300 -0
- brainplug/agent.py +749 -0
- brainplug/analysis.py +453 -0
- brainplug/app.py +184 -0
- brainplug/brain.py +184 -0
- brainplug/connect.py +354 -0
- brainplug/demo.py +165 -0
- brainplug/export.py +142 -0
- brainplug/memory.py +356 -0
- brainplug/notion_api.py +135 -0
- brainplug/pipeline.py +95 -0
- brainplug/render.py +47 -0
- brainplug/sources.py +1193 -0
- brainplug/stopwords.py +33 -0
- brainplug/sync.py +109 -0
- brainplug/templates/app.html +212 -0
- brainplug/templates/viewer.html +1050 -0
- brainplug/vendor/INTER_LICENSE +93 -0
- brainplug/vendor/THREE_LICENSE +21 -0
- brainplug/vendor/inter-latin.woff2 +0 -0
- brainplug/vendor/three.module.min.js +6 -0
- brainplug-0.4.0.dist-info/METADATA +364 -0
- brainplug-0.4.0.dist-info/RECORD +28 -0
- brainplug-0.4.0.dist-info/WHEEL +5 -0
- brainplug-0.4.0.dist-info/entry_points.txt +2 -0
- brainplug-0.4.0.dist-info/licenses/LICENSE +21 -0
- brainplug-0.4.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: brainplug
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: A second brain for you and your AI assistants: a 3D map of everything you write and a memory they plug into. 100% local.
|
|
5
|
+
Author: Juan Rodríguez
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://brainplug.app/
|
|
8
|
+
Project-URL: Source, https://github.com/juanmariarodriguez2-png/brainplug
|
|
9
|
+
Project-URL: Issues, https://github.com/juanmariarodriguez2-png/brainplug/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/juanmariarodriguez2-png/brainplug/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: second brain,memory,mcp,model context protocol,obsidian,chatgpt,claude,codex,personal knowledge,visualization,local-first
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
23
|
+
Classifier: Topic :: Text Processing :: Indexing
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: numpy>=1.24
|
|
28
|
+
Requires-Dist: scikit-learn>=1.3
|
|
29
|
+
Requires-Dist: pypdf>=4
|
|
30
|
+
Requires-Dist: mcp>=1.2
|
|
31
|
+
Requires-Dist: tzdata; sys_platform == "win32"
|
|
32
|
+
Provides-Extra: agent
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: pytest; extra == "dev"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
<!-- mcp-name: io.github.juanmariarodriguez2-png/brainplug -->
|
|
38
|
+
# Brainplug
|
|
39
|
+
|
|
40
|
+
**Plug your brain into any AI.** A second brain for you and for your AI assistants: Brainplug turns your AI chats, notes,
|
|
41
|
+
documents, mail and messages into a 3D brain you can explore, and into a memory your
|
|
42
|
+
assistants plug into: they get a short briefing instead of a pasted prompt, look up only what
|
|
43
|
+
they need, and save what they learn as notes in your Obsidian vault. Nothing is uploaded.
|
|
44
|
+
|
|
45
|
+

|
|
46
|
+
|
|
47
|
+
**[Website and live demo](https://brainplug.app/)** ·
|
|
48
|
+
**[Make yours in the browser](https://brainplug.app/app/)**
|
|
49
|
+
|
|
50
|
+
The animation and the screenshots use invented demo data, not anyone's real writing.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## A memory your AI can plug into
|
|
55
|
+
|
|
56
|
+
Every new chat starts blank, so you paste the same background again and again. With
|
|
57
|
+
Brainplug the background lives in one place, as Markdown in your own vault, and every
|
|
58
|
+
assistant reads from it and adds to it:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
uv tool install brainplug # or: pipx install brainplug
|
|
62
|
+
brainplug brain ~/Documents/MyVault # creates MyVault/Brainplug: "About me" and Memory/
|
|
63
|
+
brainplug connect ~/Documents/MyVault # adds it to Claude Desktop, Claude Code, Cursor, Codex…
|
|
64
|
+
brainplug doctor ~/Documents/MyVault # checks that it answers, end to end
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`brainplug brain ~/Documents/MyVault --draft-about` writes a first draft of your "About me"
|
|
68
|
+
note from what you have written, while it is still empty. Until the first release reaches PyPI,
|
|
69
|
+
install it from GitHub:
|
|
70
|
+
`uv tool install "brainplug @ git+https://github.com/juanmariarodriguez2-png/brainplug"`.
|
|
71
|
+
Add `--sessions` to `connect` to include what you typed to Claude Code and Codex, and put
|
|
72
|
+
export files after the vault to include what you wrote before (`… MyVault chatgpt-export.zip`).
|
|
73
|
+
|
|
74
|
+
`connect` finds the assistants installed on this computer (Claude Desktop, Claude Code, Codex,
|
|
75
|
+
Cursor, Windsurf, Gemini CLI, VS Code, LM Studio), adds one `brainplug` entry to each one's
|
|
76
|
+
settings with an absolute path (desktop apps do not see your terminal's PATH), keeps
|
|
77
|
+
everything else there, and backs the file up first. `--print` shows what it would change.
|
|
78
|
+
|
|
79
|
+
| Tool | What the assistant does with it |
|
|
80
|
+
|---|---|
|
|
81
|
+
| `context` | Gets a short briefing at the start of a conversation: your "About me" note, what you asked assistants to keep in mind, what you are writing about lately. A few hundred words instead of a pasted prompt. |
|
|
82
|
+
| `recall` | Looks something up across your notes, past chats, mail and memories, and gets excerpts rather than whole files. With `order="oldest"` it finds when you first raised something. |
|
|
83
|
+
| `remember` | Saves a decision, a preference or a fact as a note in `Brainplug/Memory`. The next assistant, in any app, finds it. With `replaces`, it corrects an older memory and keeps the old one archived. |
|
|
84
|
+
| `read`, `topic`, `timeline`, `review`, `overview` | Reads one item, follows a topic through time, sees what is growing or forgotten. |
|
|
85
|
+
| `forget` | Archives a memory when you ask. The note stays in your vault. |
|
|
86
|
+
| `exclude` | Leaves an item ("that chat isn't mine") or a whole app out of the brain, listed in `Brainplug/Excluded.md`, where deleting the line brings it back. |
|
|
87
|
+
| `name_topic` | Gives a topic a clearer name you agreed to ("Econometrics" instead of "regression · heteroskedasticity"), saved in `Brainplug/Topic names.md` and used by the map too. |
|
|
88
|
+
|
|
89
|
+
It is a [Model Context Protocol](https://modelcontextprotocol.io) server that runs on your
|
|
90
|
+
computer, so it works with assistants that can start one. It has been used end to end by
|
|
91
|
+
Codex (context, recall, remember); the read-only tools are marked as such, so assistants
|
|
92
|
+
can run them without asking each time.
|
|
93
|
+
|
|
94
|
+
### What you can say to your assistant
|
|
95
|
+
|
|
96
|
+
| You say | What happens |
|
|
97
|
+
|---|---|
|
|
98
|
+
| "What do you know about me?" | `context`: your About me note, standing preferences, what you are writing about lately. |
|
|
99
|
+
| "When did I first write about kelp forests?" | `recall` oldest first: the earliest items, with their dates and codes. |
|
|
100
|
+
| "What was I working on last spring?" | `timeline` for those months, by topic. |
|
|
101
|
+
| "What have I been neglecting?" | `review`: topics rising, fading and dormant. |
|
|
102
|
+
| "Open #k3f9a2." | `read`: your words in that item, and what it connects to in your other apps. |
|
|
103
|
+
| "Remember that I prefer short answers in Spanish." | `remember`: a note in your vault; as a standing preference it waits for your approval. |
|
|
104
|
+
| "My deadline moved to July." | `remember` with `replaces`: the old memory is archived, linked to the new one. |
|
|
105
|
+
| "That conversation isn't mine." | `exclude`: it leaves the brain; the export it came from is untouched. |
|
|
106
|
+
| "Forget what you saved about the old flat." | `forget`: the memory is archived, never deleted. |
|
|
107
|
+
| "Give my topics better names." | It suggests names from each topic's words; `name_topic` saves the ones you agree to. |
|
|
108
|
+
|
|
109
|
+
How it behaves:
|
|
110
|
+
|
|
111
|
+
- **It is all plain notes.** `Brainplug/About me.md` is yours: assistants read it and never
|
|
112
|
+
change it. Each memory is one Markdown note with its date, kind and who saved it, which you
|
|
113
|
+
can open, edit or delete in Obsidian. New memories can be found at once; notes you edit are
|
|
114
|
+
picked up in the background a little later.
|
|
115
|
+
- **Standing preferences wait for your yes.** A memory an assistant pins, or saves as a
|
|
116
|
+
preference, would shape every future conversation with every assistant, so it is saved as
|
|
117
|
+
`pinned: pending` and used only after you approve it: `brainplug brain ~/Documents/MyVault
|
|
118
|
+
--review`, or change `pending` to `true` in the note. This way a web page that tricks one
|
|
119
|
+
assistant cannot plant instructions for all of them.
|
|
120
|
+
- **Items have codes that do not change**, such as `#k3f9a2`, so an assistant that found
|
|
121
|
+
something can still open it after your files change.
|
|
122
|
+
- **It answers at once.** Your files are read in the background, and the index is kept in this
|
|
123
|
+
computer's cache folder (never a synced folder) so the next start takes a moment instead of
|
|
124
|
+
re-reading everything; `--no-cache` turns that off. Changes are picked up in the background.
|
|
125
|
+
- **It starts empty and grows.** No exports are needed to begin: point it at a folder and let
|
|
126
|
+
your assistants fill it. Add exports later to bring in what you wrote before.
|
|
127
|
+
- **Assistants are told what to save.** Only what you said or confirmed, never instructions
|
|
128
|
+
found in a web page, a file or a tool result. They can archive what they saved, not delete
|
|
129
|
+
it, and they cannot touch your own notes.
|
|
130
|
+
- **Without MCP** (the ChatGPT or Gemini websites): `brainplug brain ~/Documents/MyVault
|
|
131
|
+
--context` prints the briefing to paste, and the browser extension keeps what you type
|
|
132
|
+
there, so it still reaches the brain.
|
|
133
|
+
- What an assistant reads through these tools is sent to the AI model it runs on, like
|
|
134
|
+
anything else you show it.
|
|
135
|
+
|
|
136
|
+
## What it reads
|
|
137
|
+
|
|
138
|
+
| Source | What to give it | What is kept |
|
|
139
|
+
|---|---|---|
|
|
140
|
+
| **ChatGPT** | Export `.zip` (Settings › Data controls › Export data) | Your side of every conversation |
|
|
141
|
+
| **Claude** | Export `.zip` (Settings › Privacy › Export data) | Your side of every conversation |
|
|
142
|
+
| **Gemini** | Google Takeout › My Activity › Gemini Apps, as JSON | Your prompts, regrouped into chats |
|
|
143
|
+
| **Obsidian** | Your vault folder | Notes, frontmatter dates, `#tags`, `[[links]]` |
|
|
144
|
+
| **Notion** | "Markdown & CSV" export `.zip`, or the Notion API | Pages, tags, links between pages |
|
|
145
|
+
| **Gmail** | Google Takeout `.mbox` | Only mail **you sent**, without quoted replies or signatures |
|
|
146
|
+
| **WhatsApp** | Exported chats (`.txt` or `.zip`) | Only the messages **you sent**, one item per chat and day |
|
|
147
|
+
| **Word, PDF** | `.docx` and `.pdf` files | The text of each document |
|
|
148
|
+
| **Any notes** | A folder of `.md` / `.txt` files | The text of each file |
|
|
149
|
+
| **Live capture** | The browser extension in `extension/` | What you type into ChatGPT, Claude, Gemini, Copilot, Perplexity |
|
|
150
|
+
| **Claude Code, Codex** | `--sessions` (reads `~/.claude/projects` and `~/.codex/sessions`) | What **you typed** in each session: never the agent's replies or tool output; pasted keys are masked |
|
|
151
|
+
| **AI memory** | `Brainplug/Memory` in your vault | What your assistants were asked to remember |
|
|
152
|
+
|
|
153
|
+
Only **your own words** go in. The AI's answers and other people's mail and messages are left
|
|
154
|
+
out, so the map shows what you care about and not what you were told. Word and PDF files are
|
|
155
|
+
the exception: they are read whole, so add the ones you wrote. PDFs found *inside* a folder
|
|
156
|
+
are skipped unless you ask for them (`--pdf`).
|
|
157
|
+
|
|
158
|
+
## What you get
|
|
159
|
+
|
|
160
|
+
| | |
|
|
161
|
+
|---|---|
|
|
162
|
+
|  **Brain.** Each point is something you wrote, coloured by topic. Discs are AI chats, diamonds are notes and documents, rings are messages. |  **Galaxy.** The same points as a spiral: one arm per topic, old ideas at the core. Press play and it grows month by month. |
|
|
163
|
+
|  **Connections.** Open a point to read it and see what it relates to in your other apps. |  **Timeline.** Everything in order, filtered by topic, app or search. |
|
|
164
|
+
|  **Waves.** How each interest rises and falls over time. |  **Tables.** Cross any two things: topic by app, weekday by time of day. |
|
|
165
|
+
|  **Review.** What is growing, what you dropped, where topics meet, and a summary of you to paste into your AI. |  **Numbers.** Words written, longest streak, the hours you write at. |
|
|
166
|
+
|
|
167
|
+
The result is one HTML file that opens offline, in English or Spanish.
|
|
168
|
+
|
|
169
|
+
## Three ways to use it
|
|
170
|
+
|
|
171
|
+
### 1. In the browser, with nothing to install
|
|
172
|
+
|
|
173
|
+
Open **[the app](https://brainplug.app/app/)**, drop your files
|
|
174
|
+
and folders, and press the button. The whole analysis runs in that tab (`docs/app/engine/`,
|
|
175
|
+
plain JavaScript). Once the page has loaded it needs no connection, so you can switch your
|
|
176
|
+
wifi off before you add your files, and you can download the result.
|
|
177
|
+
|
|
178
|
+
For exports of more than about a gigabyte, use the Python version: a browser tab runs out of
|
|
179
|
+
memory before Python does.
|
|
180
|
+
|
|
181
|
+
### 2. On your computer
|
|
182
|
+
|
|
183
|
+
Needs Python 3.10 or later. Works on Windows, macOS and Linux.
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
uv tool install brainplug # or: pipx install brainplug
|
|
187
|
+
|
|
188
|
+
brainplug demo --open # try it with invented data
|
|
189
|
+
brainplug app # drag and drop, in your browser, served from 127.0.0.1 only
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Or from the terminal, with any mix of files and folders:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
brainplug build chatgpt-export.zip claude-export.zip takeout.zip ~/Documents/MyVault \
|
|
196
|
+
Sent.mbox "WhatsApp Chat with Ana.zip" thesis.pdf \
|
|
197
|
+
--me you@gmail.com --me "Your Name" --lang es -o my_brain.html --open
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
| Option | What it does |
|
|
201
|
+
|---|---|
|
|
202
|
+
| `-o, --out` | Output file (default `brainplug.html`) |
|
|
203
|
+
| `--me EMAIL_OR_NAME` | Who you are: your email (Gmail) or your name as shown in WhatsApp. Repeatable; usually detected |
|
|
204
|
+
| `--pdf` | Also read the PDFs found inside folders and ZIPs |
|
|
205
|
+
| `--notion` | Also read Notion through its API (see below) |
|
|
206
|
+
| `--sessions` | Also read what you typed to Claude Code and Codex on this computer |
|
|
207
|
+
| `--topics N` | Force the number of topics (default: chosen automatically) |
|
|
208
|
+
| `--rename N=NAME` | Rename topic N (repeatable) |
|
|
209
|
+
| `--private` | Leave titles and text out of the file, so it is safe to share |
|
|
210
|
+
| `--vault DIR` | Also write topics and chats into this Obsidian vault as linked notes |
|
|
211
|
+
| `--json FILE` | Also save the analysis as JSON |
|
|
212
|
+
| `--dataset FILE` | Also save your words as a redacted JSON Lines file (see Privacy) |
|
|
213
|
+
| `--title`, `--lang en\|es`, `--tz` | Page title, language and time zone |
|
|
214
|
+
|
|
215
|
+
### 3. Kept up to date while you write
|
|
216
|
+
|
|
217
|
+
**The extension** (`extension/`) keeps a copy of what you type into ChatGPT, Claude, Gemini,
|
|
218
|
+
Copilot and Perplexity, in that browser's own storage. It recognises a sent message by what
|
|
219
|
+
you do (Enter or a click, after which the box is empty), so it does not depend on how each
|
|
220
|
+
site builds its page, and it never reads the answers. To install it: `chrome://extensions` ›
|
|
221
|
+
turn on Developer mode › Load unpacked › choose the `extension` folder. The web app notices
|
|
222
|
+
the extension and offers to add what it has saved; the popup can also save it as a file.
|
|
223
|
+
|
|
224
|
+
**Sync** rebuilds your brain whenever something changes:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
brainplug sync --init ~/Documents/MyVault ~/Downloads/brainplug-capture.json -o my_brain.html
|
|
228
|
+
brainplug sync # rebuild once
|
|
229
|
+
brainplug sync --watch # rebuild when a note changes or a new capture file arrives
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The settings live in `brainplug.json`, next to where you ran `--init`. To have the result on
|
|
233
|
+
several devices, point `-o` (or `--vault`) at a folder that already syncs: iCloud, Google
|
|
234
|
+
Drive, Dropbox, Obsidian Sync. Brainplug has no servers of its own.
|
|
235
|
+
|
|
236
|
+
## Notes on each source
|
|
237
|
+
|
|
238
|
+
- **Gemini.** Takeout lists single prompts with no conversation, so chats are rebuilt: by
|
|
239
|
+
the conversation id when the entry has one, otherwise a new chat starts after 30 minutes
|
|
240
|
+
without a prompt. Choose JSON in Takeout; the default HTML format is read on a best-effort
|
|
241
|
+
basis.
|
|
242
|
+
- **Notion.** An export has no creation date unless the page has a date property; pages
|
|
243
|
+
without one are marked **undated** instead of being given a made-up date. To get the real
|
|
244
|
+
dates, create an internal integration at notion.so/my-integrations, share your pages with
|
|
245
|
+
it, and run `NOTION_TOKEN=secret_… brainplug build --notion`. Requests go from your
|
|
246
|
+
computer straight to api.notion.com.
|
|
247
|
+
- **Gmail.** In Takeout select Mail only and, to keep it small, just the "Sent" label.
|
|
248
|
+
Mailboxes are streamed, never loaded whole.
|
|
249
|
+
- **WhatsApp.** In a chat: More › Export chat › Without media. With two or more chats, you
|
|
250
|
+
are the sender who is in all of them; with one, pass `--me "Your Name"` if it cannot be
|
|
251
|
+
told from the file name. `03/04` is read day-first unless the file shows otherwise.
|
|
252
|
+
- **Obsidian.** Dates come from frontmatter (`created`, `date`), then from daily-note file
|
|
253
|
+
names (`2025-03-05.md`), then from the file itself.
|
|
254
|
+
|
|
255
|
+
## Privacy
|
|
256
|
+
|
|
257
|
+
- **Nothing is uploaded.** No account, no server, no tracking. The web app fetches its own
|
|
258
|
+
files when it opens and then works offline (a browser test builds a brain with the network
|
|
259
|
+
switched off); the result embeds three.js, the font and your data.
|
|
260
|
+
- **The memory server** keeps its index in this computer's cache folder (`~/Library/Caches/brainplug`,
|
|
261
|
+
`%LOCALAPPDATA%\brainplug` or `~/.cache/brainplug`); delete it any time, or use `--no-cache`.
|
|
262
|
+
`--sessions` reads the coding agents' logs where they are, keeping only what you typed.
|
|
263
|
+
See the full [privacy policy](https://brainplug.app/privacy.html).
|
|
264
|
+
- **`--private`** keeps every title, excerpt and keyword out of the file. Topic names are
|
|
265
|
+
still shown: check them and use `--rename` if one gives away too much.
|
|
266
|
+
- **`--dataset`** writes your own words as JSON Lines with emails, links, phone numbers,
|
|
267
|
+
IBANs, long numbers and @handles masked, and without titles or exact dates, in case you
|
|
268
|
+
ever want to give them to a researcher. This is masking, not anonymisation: names and
|
|
269
|
+
anything else you wrote are still there, so read the file first. Brainplug does not sell,
|
|
270
|
+
license or broker anyone's data.
|
|
271
|
+
- Your exports never belong in the repository: `.gitignore` blocks `*.zip`, `*.mbox`,
|
|
272
|
+
`conversations.json`, capture files and `brainplug.json`.
|
|
273
|
+
|
|
274
|
+
## How it works
|
|
275
|
+
|
|
276
|
+
```
|
|
277
|
+
your words ─► TF-IDF ─► LSA (SVD) ─► k-means ─► topics and their names
|
|
278
|
+
│
|
|
279
|
+
├─► nearest neighbours + [[links]] ─► connections, bridges
|
|
280
|
+
├─► brain layout (implicit volume, farthest-point sampling, PCA)
|
|
281
|
+
├─► galaxy layout (time on the radius, topics on the arms)
|
|
282
|
+
└─► waves, review and habit statistics
|
|
283
|
+
│
|
|
284
|
+
one HTML file (three.js point shader)
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
1. **Sources.** Every format becomes the same `Item`: a title, a date and the text *you*
|
|
288
|
+
wrote. The mbox reader streams messages and strips quoted replies and signatures.
|
|
289
|
+
2. **Topics.** TF-IDF with word pairs → truncated SVD → k-means, with the number of topics
|
|
290
|
+
chosen by silhouette score. Stop words cover English and Spanish.
|
|
291
|
+
3. **Connections.** Cosine nearest neighbours in the semantic space, plus the links in your
|
|
292
|
+
notes. An item nearly as close to another topic's centre as to its own is a *bridge*.
|
|
293
|
+
4. **Review.** Compares the last 60 days with the 60 before, and flags topics with no
|
|
294
|
+
activity for 90 days or more.
|
|
295
|
+
5. **Two engines.** The Python package uses scikit-learn. The web app runs a
|
|
296
|
+
dependency-free JavaScript port with its own TF-IDF, randomized SVD and k-means.
|
|
297
|
+
`tests/test_web.py` gives both the same files in every supported format and requires
|
|
298
|
+
identical numbers and matching topics.
|
|
299
|
+
|
|
300
|
+
## Project structure
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
brainplug/ the Python package
|
|
304
|
+
├── sources.py every export format → Item
|
|
305
|
+
├── notion_api.py Notion pages with real creation dates
|
|
306
|
+
├── analysis.py topics, connections, layouts, review, statistics
|
|
307
|
+
├── brain.py brain and galaxy geometry
|
|
308
|
+
├── pipeline.py files → HTML in one call
|
|
309
|
+
├── sync.py brainplug.json and --watch
|
|
310
|
+
├── memory.py the notes assistants save (Brainplug/Memory, About me.md)
|
|
311
|
+
├── agent.py the MCP server: context, recall, remember…
|
|
312
|
+
├── connect.py brainplug connect and brainplug doctor
|
|
313
|
+
├── export.py Obsidian notes and the redacted dataset
|
|
314
|
+
├── app.py local drag-and-drop app
|
|
315
|
+
├── render.py, templates/, vendor/
|
|
316
|
+
docs/ the website (GitHub Pages)
|
|
317
|
+
├── app/ the web app: index.html, worker.js, engine/ (the JavaScript port)
|
|
318
|
+
extension/ the live-capture browser extension
|
|
319
|
+
scripts/build_web.py regenerates the files the web app shares with the package
|
|
320
|
+
tests/ pytest suite; tests/browser/ drives Chrome
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
## Tests
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
pip install -e ".[dev]"
|
|
327
|
+
python -m pytest -q
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
The suite covers every loader, checks that only your own words are kept and that private
|
|
331
|
+
mode leaks nothing, runs the app, the sync command and the MCP server (including saving and
|
|
332
|
+
recalling a memory) end to end, and
|
|
333
|
+
compares the JavaScript engine with the Python one (needs Node.js). `tests/browser/` drives
|
|
334
|
+
the web app and the extension in a real Chrome; see its README.
|
|
335
|
+
|
|
336
|
+
## What has and has not been tested
|
|
337
|
+
|
|
338
|
+
Everything above is exercised by the tests, but with **invented data written in each app's
|
|
339
|
+
real export format**, not with years of anyone's real exports. In particular:
|
|
340
|
+
|
|
341
|
+
- Gemini prompt prefixes are known for English and guessed for Spanish.
|
|
342
|
+
- The extension is tested in Chrome against stand-in pages served on the real addresses,
|
|
343
|
+
not against the live sites.
|
|
344
|
+
- The Notion API reader is tested against a local stand-in for the API.
|
|
345
|
+
- The memory server is tested with the official MCP client library and was used end to end by
|
|
346
|
+
Codex as its MCP client; not yet inside Claude Desktop or Cursor themselves.
|
|
347
|
+
- CI runs the tests on Linux, macOS and Windows, and the browser tests in Chromium.
|
|
348
|
+
|
|
349
|
+
If a real export trips something up, please open an issue with the shape of the file (not
|
|
350
|
+
its contents).
|
|
351
|
+
|
|
352
|
+
## Credits
|
|
353
|
+
|
|
354
|
+
Inspired by [mindcorpus](https://mindcorpus.org/) and by the "your Obsidian vault is a
|
|
355
|
+
galaxy" visualisations. Built with [scikit-learn](https://scikit-learn.org/),
|
|
356
|
+
[three.js](https://threejs.org/), [fflate](https://github.com/101arrowz/fflate),
|
|
357
|
+
[pdf.js](https://mozilla.github.io/pdf.js/), [pypdf](https://github.com/py-pdf/pypdf) and
|
|
358
|
+
the [Inter](https://rsms.me/inter/) typeface.
|
|
359
|
+
|
|
360
|
+
## License
|
|
361
|
+
|
|
362
|
+
MIT © 2026 Juan Rodríguez. Bundled third-party files keep their own licences: three.js
|
|
363
|
+
(MIT), fflate (MIT), pdf.js (Apache 2.0) and Inter (SIL Open Font License); see the licence
|
|
364
|
+
files next to each of them.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
brainplug/__init__.py,sha256=MxaecCuYAGK6WjZP_7igHBYD8KgAIhhmWJ2DzN8D4QE,94
|
|
2
|
+
brainplug/__main__.py,sha256=cSX0pJjhWYHwXXGJtc5H1lzfi4zAcVeXmaSZhXE-jlU,16780
|
|
3
|
+
brainplug/agent.py,sha256=eFSIjvLzVUoGrU_AEt93uTykU1_ot5RUyZoGQ-xzSts,39402
|
|
4
|
+
brainplug/analysis.py,sha256=5s5gEDhTpF3zbJirQdRDAt5Hs9eFQKfSpvV8IYCFQPw,19958
|
|
5
|
+
brainplug/app.py,sha256=fKKxfP8nvhUqZlv-58tDagh5KTmIJEZ6QCcOdHaqz24,7455
|
|
6
|
+
brainplug/brain.py,sha256=JJDmprwnlHeenG6PJMUg5NyZ3CLkQ1nThiSHgeTl-NU,7098
|
|
7
|
+
brainplug/connect.py,sha256=BSUjzJ3pSDMofCZxz_eKSVbtrBRM8WZ16qP2l9k4lWA,16768
|
|
8
|
+
brainplug/demo.py,sha256=x9c1Nu6xNAThLDXIxxxNwqAyiPhpkY3aW51XjdGdjWY,9315
|
|
9
|
+
brainplug/export.py,sha256=IoRHLgatY2SfxFz9fISghBWIeGOM5DkAi4niyGJLwUk,6052
|
|
10
|
+
brainplug/memory.py,sha256=4b2iOgVfrOX4OvPgAV2zqA7BIVOyz3Hf-_FW0glpHio,15391
|
|
11
|
+
brainplug/notion_api.py,sha256=Ww_1zsXql7TIRYT46p0rLIBVt4RkSHJgy6pfL5eIxT8,5618
|
|
12
|
+
brainplug/pipeline.py,sha256=U1KVWfAr-9I1NQRPuYM7qaxjWQewQ5-z07AchE8uvjE,4043
|
|
13
|
+
brainplug/render.py,sha256=BP0GWAufecSXk6mwGcZCDsWsd44DkIK6wZdjSp1ENHM,1695
|
|
14
|
+
brainplug/sources.py,sha256=jfdqb67NogO-ytVIM8I80b5tlxrZ9VDrgExnpiCLzfM,54971
|
|
15
|
+
brainplug/stopwords.py,sha256=FV8gkIDTfeAhX5DHNj1k-tEK_IzONp5WZZ6jAL_xi70,2172
|
|
16
|
+
brainplug/sync.py,sha256=WsUCRQpnL7fsDSA61mT26DW0FrYZVzUuKbAMHX_nWzM,4235
|
|
17
|
+
brainplug/templates/app.html,sha256=tAGguc3eRBQdwbz1FKhj74IlM5B_fqt4Wgu8NVV9DFM,13747
|
|
18
|
+
brainplug/templates/viewer.html,sha256=rzsgTMGJUyoHoyB-wJvTRiJu5_T8AiesKn3-oz3vH48,69755
|
|
19
|
+
brainplug/vendor/INTER_LICENSE,sha256=Owpfyj0XlCzeiJBpiJ3tu70HXptZmWjIKpX02UTps0U,4477
|
|
20
|
+
brainplug/vendor/THREE_LICENSE,sha256=TECh72JFC4V8OyqvKUk2MEzVUtll-82dMtTFvPS6RFQ,1081
|
|
21
|
+
brainplug/vendor/inter-latin.woff2,sha256=MQDndehhbNJhG-7PojpCY9cDdYZ4m0PwNSNqLm-9TGI,48256
|
|
22
|
+
brainplug/vendor/three.module.min.js,sha256=987jx1M0SaFQXMEstRKLiePU_T1-pisF-fVGSiF0cu4,687458
|
|
23
|
+
brainplug-0.4.0.dist-info/licenses/LICENSE,sha256=-RhVkQIhJJ2U87Cy7ArtNtZdNGZH4jGrHrRsvcw6Mt4,1072
|
|
24
|
+
brainplug-0.4.0.dist-info/METADATA,sha256=AvYOxSlaFRjATbpi932Xpl4LpXKfltRZcEJ0W4-GF4o,21854
|
|
25
|
+
brainplug-0.4.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
26
|
+
brainplug-0.4.0.dist-info/entry_points.txt,sha256=h80AYsXKa_jTb2yD-vU8b7yZxF_7dJfoIq-asOEE1aw,54
|
|
27
|
+
brainplug-0.4.0.dist-info/top_level.txt,sha256=u3GnNN_C4CO783ljW1qv4FIrik41rQMgYTA0p00xUHk,10
|
|
28
|
+
brainplug-0.4.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Juan Rodríguez
|
|
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 @@
|
|
|
1
|
+
brainplug
|