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 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
- <img src="docs/screenshots/granite-note.png" alt="Granite note view" width="720">
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
- <b>Install in one prompt.</b> Your agent does the rest.
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
- ## What is Granite?
37
-
38
- Granite is a **local-first operating substrate** for the human + agent duo:
39
-
40
- - **Files you own.** Plain markdown with YAML frontmatter in `~/.granite`. No database, no lock-in, `git` works.
41
- - **Typed contracts, not folders.** Note types declare fields, hooks, indexed queries, and lifecycles. Create a `meeting` and the org stub, date default, and backlinks all fall into place automatically — deterministically, no LLM involved.
42
- - **Agent-native MCP.** The server *teaches* methodology: tools organized along `orient → research → inspect → plan → mutate`. Drop any MCP-capable LLM onto the vault and it can operate it without a system prompt.
43
- - **Hard boundary.** **No LLM, no embeddings, no scheduler inside Granite.** All intelligence lives in your agent. Granite is the disk, the schema, and the rules — never the brain.
44
-
45
- One loop: **capture → compile → query → output → lint**.
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
- ## Install prompts (copy-paste)
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
- Append to .cursor/mcp.json:
67
- { "mcpServers": { "granite": { "command": "granite", "args": ["mcp", "--vault", "~/.granite"] } } }
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
- Reload Cursor. Then call granite_wakeup.
70
- ```
85
+ Your agent brings the intelligence. Granite holds the ground truth.
71
86
 
72
- ### ChatGPT / any HTTP-MCP client
87
+ ## Try it standalone
73
88
 
74
- ```
75
- Start the Granite MCP over HTTP:
76
- granite mcp --transport http --host 127.0.0.1 --port 3321
77
- Then register http://127.0.0.1:3321 as an MCP server in your client.
89
+ ```bash
90
+ npm install -g granite-mem
91
+ granite init
92
+ granite serve
78
93
  ```
79
94
 
80
- Every one of these leaves you with the same outcome: your agent owns the loop.
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
- ## What your agent can do with it
97
+ ## Agent-native MCP
83
98
 
84
- Once connected, these are real prompts that work **out of the box**:
99
+ > "A thin MCP server exposes capabilities. A strong MCP server shapes behavior."
85
100
 
86
- > **"Process my inbox."**
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
- > **"Summarize everything I know about [[acme-corp]] before the meeting at 3pm."**
90
- > `granite_compile_context` returns a typed brief: identity, recent meetings, people, open threads, links into related syntheses. One tool call. No fuzzy matching.
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
- > **"I just talked to Alice from Acme about local-first sync."**
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. Nine types, already wired with hooks, indexed fields, and lifecycles. Open `templates/founder-os.yml` — it's 150 lines of pure YAML.
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 the graph
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