sensemaking 0.2.0 → 0.3.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.
- package/README.md +107 -126
- package/dist/cjs/cli.js +172 -182
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/commands/find.d.cts +3 -0
- package/dist/cjs/commands/find.d.ts +3 -0
- package/dist/cjs/commands/find.js +73 -0
- package/dist/cjs/commands/find.js.map +1 -0
- package/dist/cjs/commands/index.d.cts +5 -0
- package/dist/cjs/commands/index.d.ts +5 -0
- package/dist/cjs/commands/index.js +94 -0
- package/dist/cjs/commands/index.js.map +1 -0
- package/dist/cjs/commands/init.d.cts +3 -0
- package/dist/cjs/commands/init.d.ts +3 -0
- package/dist/cjs/commands/init.js +18 -0
- package/dist/cjs/commands/init.js.map +1 -0
- package/dist/cjs/commands/map.d.cts +3 -0
- package/dist/cjs/commands/map.d.ts +3 -0
- package/dist/cjs/commands/map.js +21 -0
- package/dist/cjs/commands/map.js.map +1 -0
- package/dist/cjs/commands/named.d.cts +2 -0
- package/dist/cjs/commands/named.d.ts +2 -0
- package/dist/cjs/commands/named.js +23 -0
- package/dist/cjs/commands/named.js.map +1 -0
- package/dist/cjs/commands/peek.d.cts +3 -0
- package/dist/cjs/commands/peek.d.ts +3 -0
- package/dist/cjs/commands/peek.js +69 -0
- package/dist/cjs/commands/peek.js.map +1 -0
- package/dist/cjs/commands/query.d.cts +3 -0
- package/dist/cjs/commands/query.d.ts +3 -0
- package/dist/cjs/commands/query.js +43 -0
- package/dist/cjs/commands/query.js.map +1 -0
- package/dist/cjs/commands/rebuild.d.cts +3 -0
- package/dist/cjs/commands/rebuild.d.ts +3 -0
- package/dist/cjs/commands/rebuild.js +20 -0
- package/dist/cjs/commands/rebuild.js.map +1 -0
- package/dist/cjs/commands/status.d.cts +3 -0
- package/dist/cjs/commands/status.d.ts +3 -0
- package/dist/cjs/commands/status.js +24 -0
- package/dist/cjs/commands/status.js.map +1 -0
- package/dist/cjs/commands/types.d.cts +15 -0
- package/dist/cjs/commands/types.d.ts +15 -0
- package/dist/cjs/commands/types.js +5 -0
- package/dist/cjs/commands/types.js.map +1 -0
- package/dist/cjs/commands/vault.d.cts +6 -0
- package/dist/cjs/commands/vault.d.ts +6 -0
- package/dist/cjs/commands/vault.js +94 -0
- package/dist/cjs/commands/vault.js.map +1 -0
- package/dist/cjs/commands/watch.d.cts +3 -0
- package/dist/cjs/commands/watch.d.ts +3 -0
- package/dist/cjs/commands/watch.js +173 -0
- package/dist/cjs/commands/watch.js.map +1 -0
- package/dist/cjs/config.d.cts +11 -1
- package/dist/cjs/config.d.ts +11 -1
- package/dist/cjs/config.js +82 -9
- package/dist/cjs/config.js.map +1 -1
- package/dist/cjs/db.d.cts +1 -1
- package/dist/cjs/db.d.ts +1 -1
- package/dist/cjs/db.js +107 -16
- package/dist/cjs/db.js.map +1 -1
- package/dist/cjs/errors.d.cts +1 -1
- package/dist/cjs/errors.d.ts +1 -1
- package/dist/cjs/errors.js.map +1 -1
- package/dist/cjs/features/index.d.cts +7 -0
- package/dist/cjs/features/index.d.ts +7 -0
- package/dist/cjs/features/index.js +36 -0
- package/dist/cjs/features/index.js.map +1 -0
- package/dist/cjs/features/links.d.cts +4 -0
- package/dist/cjs/features/links.d.ts +4 -0
- package/dist/cjs/features/links.js +217 -0
- package/dist/cjs/features/links.js.map +1 -0
- package/dist/cjs/features/rank.d.cts +2 -0
- package/dist/cjs/features/rank.d.ts +2 -0
- package/dist/cjs/features/rank.js +95 -0
- package/dist/cjs/features/rank.js.map +1 -0
- package/dist/cjs/features/sections.d.cts +9 -0
- package/dist/cjs/features/sections.d.ts +9 -0
- package/dist/cjs/features/sections.js +54 -0
- package/dist/cjs/features/sections.js.map +1 -0
- package/dist/cjs/features/types.d.cts +11 -0
- package/dist/cjs/features/types.d.ts +11 -0
- package/dist/cjs/features/types.js +5 -0
- package/dist/cjs/features/types.js.map +1 -0
- package/dist/cjs/graph.d.cts +7 -0
- package/dist/cjs/graph.d.ts +7 -0
- package/dist/cjs/graph.js +237 -0
- package/dist/cjs/graph.js.map +1 -0
- package/dist/cjs/index.d.cts +9 -2
- package/dist/cjs/index.d.ts +9 -2
- package/dist/cjs/index.js +39 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/output.d.cts +21 -0
- package/dist/cjs/output.d.ts +21 -0
- package/dist/cjs/output.js +112 -3
- package/dist/cjs/output.js.map +1 -1
- package/dist/cjs/scan.d.cts +3 -1
- package/dist/cjs/scan.d.ts +3 -1
- package/dist/cjs/scan.js +62 -14
- package/dist/cjs/scan.js.map +1 -1
- package/dist/cjs/verbs.d.cts +31 -0
- package/dist/cjs/verbs.d.ts +31 -0
- package/dist/cjs/verbs.js +284 -0
- package/dist/cjs/verbs.js.map +1 -0
- package/dist/esm/cli.js +63 -107
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/commands/find.d.ts +3 -0
- package/dist/esm/commands/find.js +14 -0
- package/dist/esm/commands/find.js.map +1 -0
- package/dist/esm/commands/index.d.ts +5 -0
- package/dist/esm/commands/index.js +13 -0
- package/dist/esm/commands/index.js.map +1 -0
- package/dist/esm/commands/init.d.ts +3 -0
- package/dist/esm/commands/init.js +7 -0
- package/dist/esm/commands/init.js.map +1 -0
- package/dist/esm/commands/map.d.ts +3 -0
- package/dist/esm/commands/map.js +10 -0
- package/dist/esm/commands/map.js.map +1 -0
- package/dist/esm/commands/named.d.ts +2 -0
- package/dist/esm/commands/named.js +12 -0
- package/dist/esm/commands/named.js.map +1 -0
- package/dist/esm/commands/peek.d.ts +3 -0
- package/dist/esm/commands/peek.js +12 -0
- package/dist/esm/commands/peek.js.map +1 -0
- package/dist/esm/commands/query.d.ts +3 -0
- package/dist/esm/commands/query.js +7 -0
- package/dist/esm/commands/query.js.map +1 -0
- package/dist/esm/commands/rebuild.d.ts +3 -0
- package/dist/esm/commands/rebuild.js +9 -0
- package/dist/esm/commands/rebuild.js.map +1 -0
- package/dist/esm/commands/status.d.ts +3 -0
- package/dist/esm/commands/status.js +13 -0
- package/dist/esm/commands/status.js.map +1 -0
- package/dist/esm/commands/types.d.ts +15 -0
- package/dist/esm/commands/types.js +1 -0
- package/dist/esm/commands/types.js.map +1 -0
- package/dist/esm/commands/vault.d.ts +6 -0
- package/dist/esm/commands/vault.js +29 -0
- package/dist/esm/commands/vault.js.map +1 -0
- package/dist/esm/commands/watch.d.ts +3 -0
- package/dist/esm/commands/watch.js +19 -0
- package/dist/esm/commands/watch.js.map +1 -0
- package/dist/esm/config.d.ts +11 -1
- package/dist/esm/config.js +68 -12
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/db.d.ts +1 -1
- package/dist/esm/db.js +27 -9
- package/dist/esm/db.js.map +1 -1
- package/dist/esm/errors.d.ts +1 -1
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/features/index.d.ts +7 -0
- package/dist/esm/features/index.js +14 -0
- package/dist/esm/features/index.js.map +1 -0
- package/dist/esm/features/links.d.ts +4 -0
- package/dist/esm/features/links.js +81 -0
- package/dist/esm/features/links.js.map +1 -0
- package/dist/esm/features/rank.d.ts +2 -0
- package/dist/esm/features/rank.js +17 -0
- package/dist/esm/features/rank.js.map +1 -0
- package/dist/esm/features/sections.d.ts +9 -0
- package/dist/esm/features/sections.js +41 -0
- package/dist/esm/features/sections.js.map +1 -0
- package/dist/esm/features/types.d.ts +11 -0
- package/dist/esm/features/types.js +3 -0
- package/dist/esm/features/types.js.map +1 -0
- package/dist/esm/graph.d.ts +7 -0
- package/dist/esm/graph.js +79 -0
- package/dist/esm/graph.js.map +1 -0
- package/dist/esm/index.d.ts +9 -2
- package/dist/esm/index.js +4 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/output.d.ts +21 -0
- package/dist/esm/output.js +28 -0
- package/dist/esm/output.js.map +1 -1
- package/dist/esm/scan.d.ts +3 -1
- package/dist/esm/scan.js +56 -7
- package/dist/esm/scan.js.map +1 -1
- package/dist/esm/verbs.d.ts +31 -0
- package/dist/esm/verbs.js +139 -0
- package/dist/esm/verbs.js.map +1 -0
- package/package.json +4 -4
- package/schema.json +23 -4
- package/skills/sense/EXAMPLES.md +46 -81
- package/skills/sense/SKILL.md +58 -92
package/README.md
CHANGED
|
@@ -1,169 +1,150 @@
|
|
|
1
1
|
# sensemaking
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
SQL over a tree of markdown notes: filter by frontmatter, search the prose, follow the links,
|
|
4
|
+
read the structure. A CLI that starts, answers, and exits — no server, no build step.
|
|
4
5
|
|
|
5
|
-
##
|
|
6
|
+
## Problem
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
Working with AI agents produces piles of small notes. Past a few dozen, finding the right ones
|
|
9
|
+
means grepping or reading whole folders into context. The structure that makes notes navigable —
|
|
10
|
+
frontmatter, wikilinks, headings — is exactly what an agent needs, but nothing exposes it as a
|
|
11
|
+
query surface.
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
context, or quietly rebuilds knowledge that already exists three files away.
|
|
13
|
+
`sense` indexes all of it into SQLite and reconciles against file timestamps on every query, so
|
|
14
|
+
results are never stale and nothing has to be running.
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
the pile navigable. `sensemaking` is the layer that acts on it, without an app running, a build
|
|
17
|
-
step, or you re-explaining anything.
|
|
16
|
+
## Quick start
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g sensemaking
|
|
20
|
+
cd your-notes && sense init
|
|
21
|
+
```
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
```bash
|
|
24
|
+
sense map # orient: fields, hub notes, recent changes
|
|
25
|
+
sense find "revenue OR earnings" --k 10 # locate: ranked references with excerpts
|
|
26
|
+
sense peek notes/q3-report.md # structure: outline + links, before reading
|
|
27
|
+
sense query "SELECT path FROM frontmatter WHERE has(tags, ?)" urgent
|
|
28
|
+
```
|
|
23
29
|
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
title: Ship the Q3 report
|
|
27
|
-
summary: where the Q3 numbers came from and who signed off
|
|
28
|
-
status: active
|
|
29
|
-
tags: [urgent, reports]
|
|
30
|
-
---
|
|
30
|
+
## Model
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
Every file becomes rows in four tables:
|
|
33
|
+
|
|
34
|
+
| table | holds | for |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| `frontmatter` | one column per key, plus `path`, `_mtime`, `_size`, `_rank` | filtering |
|
|
37
|
+
| `content` | FTS5 index: `title`, `summary`, `text` | search and ranking |
|
|
38
|
+
| `links` | `src`, `target` as written, `dst` resolved (`NULL` = dead link) | graph |
|
|
39
|
+
| `sections` | heading, `level`, `start_line`, `end_line`, `tokens` estimate | structure |
|
|
40
|
+
|
|
41
|
+
Results are references — path, title, summary, excerpt — never file contents. Reading happens
|
|
42
|
+
afterward through the filesystem, scoped to the line ranges `peek` returns. This is the
|
|
43
|
+
[just-in-time context pattern](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents):
|
|
44
|
+
the agent holds lightweight identifiers and loads payloads only when needed.
|
|
45
|
+
|
|
46
|
+
Measured costs: a `find` row is ~20–40 tokens, a `peek` is ~17% of reading the file, and the
|
|
47
|
+
section it points at is a direct `Read` range.
|
|
34
48
|
|
|
35
49
|
```sql
|
|
36
|
-
--
|
|
37
|
-
SELECT f.path, content.title,
|
|
50
|
+
-- filter and search compose in one query
|
|
51
|
+
SELECT f.path, content.title, snippet(content, -1, '«', '»', '…', 10) AS hit
|
|
38
52
|
FROM frontmatter f JOIN content ON content.path = f.path
|
|
39
53
|
WHERE f.status = 'active' AND content MATCH 'revenue'
|
|
40
54
|
ORDER BY bm25(content, 10.0, 5.0, 1.0) LIMIT 10
|
|
41
55
|
```
|
|
42
56
|
|
|
43
|
-
|
|
44
|
-
path, title, summary, matching excerpt — is enough to decide whether to open the file, without
|
|
45
|
-
carrying the file. On a real 26-note vault that's a few hundred tokens, against ~6,000 to read the
|
|
46
|
-
three files it points at. Cheap enough to run before deciding what to open; reading afterward is
|
|
47
|
-
the expensive step, and it happens through the filesystem, not SQL.
|
|
57
|
+
## Verbs
|
|
48
58
|
|
|
49
|
-
|
|
59
|
+
| verb | does |
|
|
60
|
+
|---|---|
|
|
61
|
+
| `map` | doc count, frontmatter field coverage, top hubs by link rank, recent changes |
|
|
62
|
+
| `find "<terms>" [--where "<sql>"] [--k n]` | BM25 + link-graph expansion, fused; `via` marks each row `match`, `link`, or `match+link` |
|
|
63
|
+
| `peek <path>` | frontmatter + heading outline (`[L143-162, ~380t]`) + links both ways, capped at 20 per list |
|
|
64
|
+
| `query "<sql>" [params...]` | ad-hoc SQL over all four tables; `?` binds positional args |
|
|
50
65
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
Obsidian, not a server, not a daemon.
|
|
66
|
+
`find` seeds a personalized-PageRank walk with the BM25 matches, so a note that never contains
|
|
67
|
+
the terms but is linked from ones that do still surfaces. Invalid FTS5 syntax falls back to
|
|
68
|
+
OR over the words. `--where` takes a frontmatter condition against alias `f`.
|
|
69
|
+
`--format json` on any verb returns structured output.
|
|
56
70
|
|
|
57
|
-
##
|
|
71
|
+
## Config
|
|
58
72
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
cd your-notes && sense init # writes a minimal sense.config.json (globs only, no queries)
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
Query immediately — ad-hoc SQL needs no config beyond the globs:
|
|
65
|
-
|
|
66
|
-
```
|
|
67
|
-
sense query "SELECT … FROM frontmatter" # ad-hoc SQL; positional args bind to ? placeholders
|
|
68
|
-
sense query "…" --format json # structured output (the default is a table)
|
|
69
|
-
sense --list # what named queries exist
|
|
70
|
-
sense status | rebuild # cache info / delete .sense/ and re-crawl
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
When a query proves worth reusing, name it in `sense.config.json` (plain JSON; the `$schema` line
|
|
74
|
-
gives your editor autocomplete and validation) and run it as `sense <name> [params...]`:
|
|
73
|
+
`sense init` writes `sense.config.json`; discovery walks up from cwd like git
|
|
74
|
+
(`--config <path>` overrides). Name reusable queries and run them as `sense <name> [params...]`:
|
|
75
75
|
|
|
76
76
|
```json
|
|
77
77
|
{
|
|
78
78
|
"$schema": "https://unpkg.com/sensemaking/schema.json",
|
|
79
|
-
"version":
|
|
79
|
+
"version": 2,
|
|
80
80
|
"scan": { "include": ["**/*.md"] },
|
|
81
|
+
"features": { "links": true, "sections": true, "rank": true },
|
|
81
82
|
"queries": {
|
|
82
|
-
"by-tag": "SELECT path, title
|
|
83
|
+
"by-tag": "SELECT path, title FROM frontmatter WHERE has(tags, ?) ORDER BY path"
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
86
|
```
|
|
86
87
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
`
|
|
90
|
-
|
|
91
|
-
The one custom SQL function is `has(field, value)`: array membership on a JSON-array field (like
|
|
92
|
-
`tags`), substring match on a string, always false on a missing key. Reserved names: `path`,
|
|
93
|
-
`_mtime`, `_size`, `content`.
|
|
88
|
+
Features toggle independently; disabling one degrades its verb instead of failing it (`find`
|
|
89
|
+
goes BM25-only without `links`, `map` drops hubs without `rank`, `peek` drops the outline
|
|
90
|
+
without `sections`). Toggling rebuilds the cache. Older config versions auto-migrate on load,
|
|
91
|
+
noted on stderr.
|
|
94
92
|
|
|
95
|
-
|
|
93
|
+
## Reference
|
|
96
94
|
|
|
97
|
-
`
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
95
|
+
- `has(field, value)` — the one custom SQL function: array membership on JSON-array fields,
|
|
96
|
+
substring on strings, false on missing keys.
|
|
97
|
+
- Reserved frontmatter keys (dropped with a warning): `path`, `_mtime`, `_size`, `_rank`,
|
|
98
|
+
`content`, `links`, `sections`.
|
|
99
|
+
- FTS5 syntax in `MATCH`: `a OR b`, `"phrase"`, `pref*`, `NEAR(a b, 5)`, `summary: term`.
|
|
100
|
+
Stemmed; markdown is stripped at index time. `bm25(content, 10.0, 5.0, 1.0)` weights title
|
|
101
|
+
over summary over body.
|
|
102
|
+
- A one-line `summary:` in frontmatter is both a selectable column and a weighted search field.
|
|
103
|
+
- Exit codes: `0` ok, `1` error (SQLite message verbatim), `2` usage.
|
|
104
|
+
- Frontmatter parsing is lenient: syntax errors (an alias starting with `@`, say) are per-file
|
|
105
|
+
warnings and the values are still indexed.
|
|
104
106
|
|
|
105
|
-
|
|
106
|
-
dump your notes into an agent's context — reaching it takes an explicit join. Select `path`,
|
|
107
|
-
`title`, `summary`, and a `snippet()`, keep a `LIMIT`, and read the files worth reading. `sense`
|
|
108
|
-
warns on stderr when a result grows past 50 KB.
|
|
107
|
+
## Scale
|
|
109
108
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
Every query starts with a freshness check against the cache in `.sense/`; only changed files are
|
|
110
|
+
re-parsed. Measured per release in [BENCHMARKING.md](BENCHMARKING.md) — at 6,566 notes: full
|
|
111
|
+
crawl ~5 s, warm query ~100 ms, one-file change ~200 ms. `sense watch` (optional) moves
|
|
112
|
+
re-parsing into the background — see [WATCH.md](WATCH.md). `sense rebuild` deletes the cache and
|
|
113
|
+
re-crawls.
|
|
113
114
|
|
|
114
|
-
|
|
115
|
+
## For AI agents
|
|
115
116
|
|
|
116
117
|
```bash
|
|
117
|
-
|
|
118
|
-
npx skills add kmalakoff/sensemaking # the agent skill (add -g for global, -a claude-code to target)
|
|
118
|
+
npx skills add kmalakoff/sensemaking # -g for global, -a claude-code to target
|
|
119
119
|
```
|
|
120
120
|
|
|
121
|
-
The skill teaches
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
- **
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
-
|
|
148
|
-
AND/OR/ORDER BY — at which point you've started writing a worse query engine.
|
|
149
|
-
|
|
150
|
-
`sensemaking` is deliberately thin glue: [gray-matter](https://github.com/jonschlinkert/gray-matter)
|
|
151
|
-
parses, [remove-markdown](https://github.com/zuchka/remove-markdown) cleans the prose for indexing,
|
|
152
|
-
[fast-glob](https://github.com/mrmlnc/fast-glob) walks, and Node's built-in SQLite (`node:sqlite`)
|
|
153
|
-
does all the querying. Three small dependencies, no native builds, no background services required.
|
|
154
|
-
|
|
155
|
-
## Roadmap
|
|
156
|
-
|
|
157
|
-
Vector similarity is the natural next facet — a `doc_vec` table joined the same way `content` is,
|
|
158
|
-
so semantic recall composes with the frontmatter filter instead of living in a separate tool
|
|
159
|
-
(`SELECT path, distance`, never the embedding). It's deferred, not planned: today it would require
|
|
160
|
-
a native SQLite extension (sqlite-vec is pre-v1 and ships platform binaries), which breaks the
|
|
161
|
-
no-native-builds line above. It becomes worth revisiting when Node can do it dependency-free — and
|
|
162
|
-
only if BM25 demonstrably misses things; on a curated vault of a few hundred notes it often
|
|
163
|
-
doesn't.
|
|
164
|
-
|
|
165
|
-
Beyond that, the corpus model isn't tied to markdown — anything carrying structured metadata
|
|
166
|
-
(document properties, sidecar JSON) can join it without changing the query surface.
|
|
121
|
+
The skill teaches the descent: `map` to orient, `find` to locate, `peek` before reading,
|
|
122
|
+
`Read` line ranges instead of files.
|
|
123
|
+
|
|
124
|
+
## Prior art
|
|
125
|
+
|
|
126
|
+
- [Effective context engineering for AI agents](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents)
|
|
127
|
+
(Anthropic): agents should hold lightweight identifiers — file paths, links — and load payloads
|
|
128
|
+
just in time, because context is a finite resource. The four verbs implement that pattern as a CLI.
|
|
129
|
+
- [llm-wiki](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f) (Karpathy): an
|
|
130
|
+
agent-maintained wiki navigated by an `index.md` and links, which he notes needs real search
|
|
131
|
+
infrastructure past a few hundred pages. `sense map` derives that index from the notes instead of
|
|
132
|
+
maintaining it; `find` is the hybrid local search it calls for.
|
|
133
|
+
|
|
134
|
+
## Alternatives
|
|
135
|
+
|
|
136
|
+
- **Obsidian Bases/Dataview** — same filters, but only inside the running app; agents can't
|
|
137
|
+
query it headless.
|
|
138
|
+
- **Index-on-build tools (MarkdownDB)** — query a snapshot; `sense` reconciles on every query.
|
|
139
|
+
- **Note CLIs (zk)** — fixed schema; `sense` filters on arbitrary frontmatter.
|
|
140
|
+
- **RAG / vector stores** — similarity can't express `WHERE status = 'active'`. Vector recall is
|
|
141
|
+
planned as an optional `embed` feature (pure-JS provider package, fused into `find`) — not
|
|
142
|
+
blocked (`node:sqlite` can load extensions since Node 22.13), just deferred until BM25 + links
|
|
143
|
+
measurably miss.
|
|
144
|
+
|
|
145
|
+
Dependencies: [yaml](https://github.com/eemeli/yaml),
|
|
146
|
+
[remove-markdown](https://github.com/zuchka/remove-markdown),
|
|
147
|
+
[fast-glob](https://github.com/mrmlnc/fast-glob), and Node's built-in SQLite. No native builds.
|
|
167
148
|
|
|
168
149
|
## License
|
|
169
150
|
|