granite-mem 0.1.9 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +196 -56
- package/dist/index.js +6050 -4058
- package/dist/public/app.js +9 -9
- package/dist/public/index.html +1 -0
- package/dist/public/style.css +1 -1
- package/package.json +18 -6
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 The Vibe Company
|
|
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.
|
package/README.md
CHANGED
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
# Granite
|
|
2
2
|
|
|
3
|
+
<p align="center">
|
|
4
|
+
<a href="https://www.npmjs.com/package/granite-mem"><img src="https://img.shields.io/npm/v/granite-mem?color=111111" alt="npm version"></a>
|
|
5
|
+
<a href="https://www.npmjs.com/package/granite-mem"><img src="https://img.shields.io/npm/dm/granite-mem?color=111111" alt="npm downloads"></a>
|
|
6
|
+
<a href="https://github.com/The-Vibe-Company/Granite/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/The-Vibe-Company/Granite/ci.yml?branch=main&label=tests&color=111111" alt="CI status"></a>
|
|
7
|
+
<a href="LICENSE"><img src="https://img.shields.io/github/license/The-Vibe-Company/Granite?color=111111" alt="MIT license"></a>
|
|
8
|
+
<a href="https://github.com/The-Vibe-Company/Granite/stargazers"><img src="https://img.shields.io/github/stars/The-Vibe-Company/Granite?style=social" alt="GitHub stars"></a>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
3
11
|
> **The personal OS your agent runs on.**
|
|
4
|
-
> Markdown files. One SQLite index. A contract your agent already knows how to operate.
|
|
12
|
+
> Markdown files. One SQLite index. A typed contract your agent already knows how to operate.
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<img src="docs/screenshots/granite-graph.png" alt="Granite constellation graph" width="720">
|
|
16
|
+
</p>
|
|
5
17
|
|
|
6
18
|
<p align="center">
|
|
7
|
-
<
|
|
19
|
+
<b>Install it with your agent.</b> Or run it standalone as a local markdown knowledge graph.
|
|
8
20
|
</p>
|
|
9
21
|
|
|
10
22
|
<p align="center">
|
|
11
|
-
<
|
|
23
|
+
<a href="#your-vault-in-the-cloud"><img src="https://img.shields.io/badge/☁️_Deploy_your_Granite-one_command,_sleeps_when_idle-111111?style=for-the-badge" alt="Deploy your Granite"></a>
|
|
12
24
|
</p>
|
|
13
25
|
|
|
14
26
|
---
|
|
@@ -33,69 +45,69 @@ Sixty seconds later you have a live vault, a connected agent that **knows how to
|
|
|
33
45
|
|
|
34
46
|
That's the thesis of this project.
|
|
35
47
|
|
|
36
|
-
##
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
## See it
|
|
49
|
+
|
|
50
|
+
<table>
|
|
51
|
+
<tr>
|
|
52
|
+
<td width="50%">
|
|
53
|
+
<img src="docs/screenshots/granite-graph.png" alt="Granite constellation graph">
|
|
54
|
+
<br>
|
|
55
|
+
<sub><b>Constellation graph.</b> Browse the vault as communities, hubs, and links.</sub>
|
|
56
|
+
</td>
|
|
57
|
+
<td width="50%">
|
|
58
|
+
<img src="docs/screenshots/granite-search.png" alt="Granite command palette search">
|
|
59
|
+
<br>
|
|
60
|
+
<sub><b>Command palette.</b> Search the vault and jump straight into the graph context.</sub>
|
|
61
|
+
</td>
|
|
62
|
+
</tr>
|
|
63
|
+
<tr>
|
|
64
|
+
<td width="50%">
|
|
65
|
+
<img src="docs/screenshots/granite-preview.png" alt="Granite note preview">
|
|
66
|
+
<br>
|
|
67
|
+
<sub><b>Graph-aware reading.</b> Preview notes without losing the surrounding context.</sub>
|
|
68
|
+
</td>
|
|
69
|
+
<td width="50%">
|
|
70
|
+
<img src="docs/screenshots/granite-note.png" alt="Granite reader view">
|
|
71
|
+
<br>
|
|
72
|
+
<sub><b>Floating reader.</b> Open a note without leaving the constellation.</sub>
|
|
73
|
+
</td>
|
|
74
|
+
</tr>
|
|
75
|
+
</table>
|
|
46
76
|
|
|
47
|
-
##
|
|
48
|
-
|
|
49
|
-
### Claude Code / Claude Desktop
|
|
50
|
-
|
|
51
|
-
```
|
|
52
|
-
Install Granite for me:
|
|
53
|
-
npm install -g granite-mem
|
|
54
|
-
granite init --template founder-os
|
|
55
|
-
claude mcp add granite -- granite mcp --vault ~/.granite
|
|
56
|
-
After restart, call granite_wakeup and tell me what the vault looks like.
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### Cursor
|
|
77
|
+
## What is Granite?
|
|
60
78
|
|
|
61
|
-
|
|
62
|
-
Run these commands, then add Granite to .cursor/mcp.json:
|
|
63
|
-
npm install -g granite-mem
|
|
64
|
-
granite init --template founder-os
|
|
79
|
+
A local-first markdown store with an opinionated flow. **No AI inside** — just plain files on disk, indexed by SQLite, queried deterministically.
|
|
65
80
|
|
|
66
|
-
|
|
67
|
-
|
|
81
|
+
- **Imposed flow.** Capture, compile, query, output, lint. The shape is fixed; the content is yours.
|
|
82
|
+
- **Four default note types** — `note`, `source`, `synthesis`, `output`. Add your own in `granite.yml` when your life grows a new shape.
|
|
83
|
+
- **A specialized MCP** that teaches your agent how to use the vault. Drop any MCP-capable agent on it and it knows how to operate, no system prompt required.
|
|
68
84
|
|
|
69
|
-
|
|
70
|
-
```
|
|
85
|
+
Your agent brings the intelligence. Granite holds the ground truth.
|
|
71
86
|
|
|
72
|
-
|
|
87
|
+
## Try it standalone
|
|
73
88
|
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
89
|
+
```bash
|
|
90
|
+
npm install -g granite-mem
|
|
91
|
+
granite init
|
|
92
|
+
granite serve
|
|
78
93
|
```
|
|
79
94
|
|
|
80
|
-
|
|
95
|
+
That starts with the default knowledge model: `note`, `source`, `synthesis`, and `output`. Add `--template founder-os` when you want people, organizations, meetings, and learnings wired in from the start.
|
|
81
96
|
|
|
82
|
-
##
|
|
97
|
+
## Agent-native MCP
|
|
83
98
|
|
|
84
|
-
|
|
99
|
+
> "A thin MCP server exposes capabilities. A strong MCP server shapes behavior."
|
|
85
100
|
|
|
86
|
-
|
|
87
|
-
> The agent calls `granite_wakeup`, lists inbox notes, classifies each, rewrites them as durable `note`s, links them to existing people/orgs, and promotes `review_state: draft → reviewed`.
|
|
101
|
+
Granite's MCP surface is intention-first:
|
|
88
102
|
|
|
89
|
-
|
|
90
|
-
|
|
103
|
+
- `granite_wakeup` to orient
|
|
104
|
+
- `granite_research_topic` to inspect existing knowledge before writing
|
|
105
|
+
- `granite_query` for structured filters over typed notes
|
|
106
|
+
- `granite_compile_context` to assemble a graph-aware brief
|
|
107
|
+
- `granite_plan_garden` to decide what to improve next
|
|
108
|
+
- `granite_capture_knowledge` to write with protocol fields and type contracts
|
|
91
109
|
|
|
92
|
-
|
|
93
|
-
> `granite_capture_knowledge` creates a `meeting`, fills `date: today` via a hook, resolves `organization: Acme` to a slug (creates a stub if missing), links `attendees: [[alice]]`, and suggests three follow-up notes.
|
|
94
|
-
|
|
95
|
-
> **"Garden the vault."**
|
|
96
|
-
> `granite_plan_garden` returns the highest-leverage clusters to revisit. The agent opens the top three, revises them, and flags lifecycle transitions (`stale_days`) for your review.
|
|
97
|
-
|
|
98
|
-
Every one of those is a single MCP round-trip, deterministic, auditable in `git log`.
|
|
110
|
+
The point is not to give an agent a file browser. The point is to give it a workflow it can follow.
|
|
99
111
|
|
|
100
112
|
## Types as active contracts
|
|
101
113
|
|
|
@@ -125,7 +137,7 @@ note_types:
|
|
|
125
137
|
- `indexed_fields` — makes `granite_query { type: meeting, where: { date: { gte: "2026-01-01" } } }` O(1) and deterministic
|
|
126
138
|
- `lifecycle` — `granite doctor` surfaces stale notes so gardening never drifts
|
|
127
139
|
|
|
128
|
-
Add a type when your life has a new shape. The core stays small.
|
|
140
|
+
Add a type when your life has a new shape. The core stays small. For the formal protocol, see [docs/GRANITE_OBJECT_STANDARD.md](docs/GRANITE_OBJECT_STANDARD.md).
|
|
129
141
|
|
|
130
142
|
## Templates
|
|
131
143
|
|
|
@@ -134,7 +146,7 @@ granite init # minimal: note / source / synthesis / out
|
|
|
134
146
|
granite init --template founder-os # + person / organization / meeting / learning
|
|
135
147
|
```
|
|
136
148
|
|
|
137
|
-
`founder-os` is the full personal-OS starter: people you talk to, orgs you work with, meetings you had, things you learned.
|
|
149
|
+
`founder-os` is the full personal-OS starter: people you talk to, orgs you work with, meetings you had, things you learned. Eight types, already wired with hooks, indexed fields, and lifecycles. Open `templates/founder-os.yml` — it's 150 lines of pure YAML.
|
|
138
150
|
|
|
139
151
|
## The hard boundary
|
|
140
152
|
|
|
@@ -166,10 +178,138 @@ Your agent reads these before writing and sets them as it works. You inherit a f
|
|
|
166
178
|
- Markdown files are the source of truth; the SQLite index in `~/.granite/index.db` is derived state and can be rebuilt at any time
|
|
167
179
|
- no cloud, no telemetry, no account
|
|
168
180
|
- `git init` your vault and you have versioning for free
|
|
169
|
-
- `granite serve` gives you a local web UI — browse, search, explore
|
|
181
|
+
- `granite serve` gives you a local web UI — browse, search, explore local and cloud graphs
|
|
182
|
+
- `granite daemon start` runs MCP + web UI in one background process
|
|
183
|
+
|
|
184
|
+
## Your vault in the cloud
|
|
185
|
+
|
|
186
|
+
One command deploys a personal serverless Granite on [Fly.io Sprites](https://sprites.dev): a real persistent filesystem, an MCP endpoint that **wakes on request** (100–500 ms warm) and **sleeps when idle**. Idle cost ≈ storage only — a markdown vault is a few MB, so cents per month.
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
export SPRITES_TOKEN=… # from sprites.dev — your account, your sprite, your data
|
|
190
|
+
npx granite-mem deploy
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Or store the Sprites API token once in a user-scoped Granite credentials file:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
granite deploy login --token <sprites-token>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
That writes `~/.granite/config/sprites.json` (mode `0600` where supported). It works on macOS, Linux, and Windows via the user's home directory. Commands resolve credentials in this order: `--token`, `SPRITES_TOKEN`, then the stored file. Remove it with `granite deploy logout`.
|
|
200
|
+
|
|
201
|
+
That prints an MCP URL + bearer token ready to paste into Claude Code or Cursor:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
claude mcp add --transport http granite https://<your-sprite>.sprites.app/mcp \
|
|
205
|
+
--header "Authorization: Bearer <token>"
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
There is no central admin, no Granite cloud account, no relay: `granite deploy` provisions a sprite **you** own and pay for directly.
|
|
209
|
+
|
|
210
|
+
Manage instances from any machine after `deploy login`, or with `SPRITES_TOKEN`:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
granite deploy login --token <sprites-token>
|
|
214
|
+
granite deploy work # a second instance (own vault, own token, own URL)
|
|
215
|
+
granite deploy list # all instances: version, health, MCP URL
|
|
216
|
+
granite deploy status --show-token
|
|
217
|
+
granite deploy # re-run = upgrade that instance to your CLI version
|
|
218
|
+
granite deploy --all # bulk remote update of every instance
|
|
219
|
+
granite deploy destroy work # permanent — asks for confirmation
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Browse local and deployed vaults from the same local UI:
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
SPRITES_TOKEN=… granite serve
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
`granite serve` discovers your managed Sprites using `SPRITES_TOKEN` or the stored `~/.granite/config/sprites.json` token. It keeps MCP bearer tokens on the local server and proxies read-only graph/search/note requests to the selected cloud instance. Use `granite serve --no-cloud` to browse only the local vault.
|
|
229
|
+
|
|
230
|
+
Notes:
|
|
231
|
+
|
|
232
|
+
- Document parsing (PDF/DOCX/XLSX/PPTX) is **disabled in cloud deployments** (`GRANITE_DISABLE_DOCUMENT_PARSING=1`). Extract and import documents on your local Granite.
|
|
233
|
+
- Cloud instances expose MCP plus an authenticated read-only web API for the local UI switcher; note creation in the web UI remains local-only.
|
|
234
|
+
- The Sprites API token is local user configuration at `~/.granite/config/sprites.json`; it is not written to the vault notes and is excluded from Granite sync manifests.
|
|
235
|
+
- The vault lives at `/home/sprite/.granite` on the sprite, on durable object-storage-backed disk. There is no export/backup command in v1 — treat the sprite as the single copy for now.
|
|
236
|
+
|
|
237
|
+
### Advanced: run the HTTP MCP server yourself
|
|
238
|
+
|
|
239
|
+
Granite can expose the MCP server over HTTP anywhere you can run Node. When binding outside localhost, a bearer token is required:
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
export GRANITE_MCP_TOKEN="$(openssl rand -hex 32)"
|
|
243
|
+
granite mcp --vault ~/.granite \
|
|
244
|
+
--transport http \
|
|
245
|
+
--host 0.0.0.0 \
|
|
246
|
+
--port 3321 \
|
|
247
|
+
--web-api
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Clients must send the token on every MCP request:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
claude mcp add --transport http granite https://granite.example.com/mcp \
|
|
254
|
+
--header "Authorization: Bearer $GRANITE_MCP_TOKEN"
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
A generic `Dockerfile` is included for self-hosting on your own infra (build it yourself; no public image is published). The `/health` endpoint is unauthenticated for platform checks. Do not expose `granite serve` or the web UI port `4321` on the public internet; the web UI is local-only and has no authentication. If `--web-api` is enabled on the HTTP MCP server, `/api/*` and `/assets/*` are guarded by the same bearer token as `/mcp`.
|
|
258
|
+
|
|
259
|
+
## Direct sync
|
|
260
|
+
|
|
261
|
+
Granite sync is direct machine-to-machine. Run it over LAN, Tailscale, or a private DNS name; there is no relay, hosted worker, billing tier, or cloud authority.
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# Machine A
|
|
265
|
+
granite sync access grant ipad --role read
|
|
266
|
+
granite sync access grant desktop --role write
|
|
267
|
+
granite sync serve --host 0.0.0.0 --port 8765
|
|
268
|
+
|
|
269
|
+
# Read-only Machine B
|
|
270
|
+
granite sync remote add macbook http://100.x.y.z:8765 --token <read-token>
|
|
271
|
+
granite sync pull macbook
|
|
272
|
+
granite sync watch macbook --direction pull --interval 30
|
|
273
|
+
|
|
274
|
+
# Write-capable Machine C
|
|
275
|
+
granite sync remote add macbook http://100.x.y.z:8765 --token <write-token>
|
|
276
|
+
granite sync run macbook
|
|
277
|
+
granite sync watch macbook --interval 30
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Conflicts default to manual preservation with `.conflict.<device>.<timestamp>.md` files. For a personal multi-device setup, pick the device that wins conflicts:
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
granite sync config --policy primary-wins --primary-this-device
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
MCP is scoped to one vault per server. Launch a read-only MCP server when an agent should inspect a synced vault without mutating it:
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
granite mcp --vault ~/.granite --role read
|
|
290
|
+
granite mcp --vault ~/.granite --role write
|
|
291
|
+
```
|
|
170
292
|
|
|
171
293
|
For the full CLI, run `granite --help`. For development, see [CLAUDE.md](CLAUDE.md).
|
|
172
294
|
|
|
295
|
+
## Roadmap & status
|
|
296
|
+
|
|
297
|
+
Granite is pre-1.0. The current release is **v0.1.9**, with the major agent-native loop pieces now in place: typed contracts, wakeup snapshots, deterministic garden planning, document import, daemon mode, and the constellation graph.
|
|
298
|
+
|
|
299
|
+
Read [CHANGELOG.md](CHANGELOG.md) for release history. The product boundary stays fixed: Granite stores and indexes local knowledge; agents bring the intelligence.
|
|
300
|
+
|
|
301
|
+
## Contributing
|
|
302
|
+
|
|
303
|
+
Issues and focused PRs are welcome.
|
|
304
|
+
|
|
305
|
+
For local development, read [CLAUDE.md](CLAUDE.md). The key product rule is simple: no embedded LLM, no vector store, no autonomous scheduler inside Granite.
|
|
306
|
+
|
|
307
|
+
> Karpathy wrote that there was room for "an incredible new product instead of a hacky collection of scripts" around LLM knowledge bases.
|
|
308
|
+
>
|
|
309
|
+
> Granite is the product that answers that call.
|
|
310
|
+
>
|
|
311
|
+
> — [@karpathy on LLM knowledge bases](https://x.com/karpathy/status/2039805659525644595)
|
|
312
|
+
|
|
173
313
|
## Philosophy
|
|
174
314
|
|
|
175
315
|
- local-first beats cloud dependence for personal memory
|