librian 0.1.1 → 0.2.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/CHANGELOG.md +39 -2
- package/README.md +39 -12
- package/dist/cli.js +1050 -152
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,13 +4,50 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [0.2.0] - 2026-11-08
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **`changes` tool.** A fifth tool per docs folder (`team__changes`) lists the
|
|
12
|
+
blocks added, changed or removed since the session start, or since a
|
|
13
|
+
`since` time you pass (ISO 8601, local time when it has no zone), with their
|
|
14
|
+
current `path:start-end`. Pass the `As of` time of one call as `since` to get
|
|
15
|
+
only what changed after it. Added and removed files are one line each; the
|
|
16
|
+
output stays within the byte limit and continues with `More: offset=N`.
|
|
17
|
+
- **A history of block hashes.** `~/.librian/history.db` (Node's built-in
|
|
18
|
+
`node:sqlite`, no new dependency) keeps each docs file's heading lines and a
|
|
19
|
+
short hash of every block, never the text, for 30 days. It is shared by all
|
|
20
|
+
sessions, survives restarts and is never written inside a docs folder. A
|
|
21
|
+
running server also refreshes it every 5 minutes and stops by itself when its
|
|
22
|
+
parent process is gone. If the file cannot be used or was deleted while a
|
|
23
|
+
server runs, only `changes` reports it.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- **Uninstall also removes `history.db`.** The confirmation says so; docs
|
|
28
|
+
folders and the catalog are kept.
|
|
29
|
+
- **Server shutdown has one path.** stdin end, a broken stdout, an uncaught
|
|
30
|
+
exception, SIGINT and SIGTERM all stop the timer and the history, then close
|
|
31
|
+
the server.
|
|
32
|
+
|
|
33
|
+
## [0.1.2] - 2026-11-08
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- **Search ranks by BM25 instead of hit count.** After the headings rule, blocks
|
|
38
|
+
are ordered by a BM25 score (no IDF), so a short, exact block is no longer
|
|
39
|
+
pushed down by a long block that repeats the words many times. The `N hits`
|
|
40
|
+
on a result row is unchanged.
|
|
41
|
+
- **Generic examples.** The README, the `list` tool description and the usage
|
|
42
|
+
text use neutral example names (`guide/api`, `team`). Behaviour is unchanged.
|
|
43
|
+
|
|
7
44
|
## [0.1.1] - 2026-11-08
|
|
8
45
|
|
|
9
46
|
### Added
|
|
10
47
|
|
|
11
48
|
- **`librian add [<folder>]`.** Adds a docs folder without opening the menu:
|
|
12
49
|
run it inside the docs folder, or pass the path. It counts the markdown
|
|
13
|
-
files, asks `Add it as "
|
|
50
|
+
files, asks `Add it as "team_docs"? (Y/n)` and adds the entry. It refuses
|
|
14
51
|
your home folder and a drive root (exit code 2), says `Already added as …`
|
|
15
52
|
(exit code 0) for a folder that is already there, and adds nothing when the
|
|
16
53
|
input ends.
|
|
@@ -70,5 +107,5 @@ First release.
|
|
|
70
107
|
`~/.librian/catalog.json`; `LIBRIAN_HOME` moves both.
|
|
71
108
|
- **One server for all folders.** `librian serve --catalog` is what the AI
|
|
72
109
|
services run: it offers the four tools for each entry, prefixed with the
|
|
73
|
-
entry name (`
|
|
110
|
+
entry name (`team__read`). `librian serve --root <folder>` serves a single
|
|
74
111
|
folder with unprefixed tools, for registering by hand.
|
package/README.md
CHANGED
|
@@ -40,22 +40,22 @@ Choose an entry to **Edit**, **Check** (file count, total size, largest files) o
|
|
|
40
40
|
**Add docs folder** asks for one thing, the folder, and then adds it:
|
|
41
41
|
|
|
42
42
|
```
|
|
43
|
-
? Docs folder › D:\workspace\projects\
|
|
43
|
+
? Docs folder › D:\workspace\projects\team\team.docs
|
|
44
44
|
107 markdown files · 4.1M
|
|
45
|
-
? Add it as "
|
|
46
|
-
✔ Added
|
|
45
|
+
? Add it as "team_docs"? (Y/n)
|
|
46
|
+
✔ Added team_docs. Open a new session to use team_docs__read and the other tools.
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
A folder that does not exist is refused with the reason and asked again with what you typed. A folder that is already added says `Already added as "
|
|
49
|
+
A folder that does not exist is refused with the reason and asked again with what you typed. A folder that is already added says `Already added as "team".` and takes you to that entry. A folder without markdown files gets a warning and the question defaults to No. Esc saves nothing. The entry gets the default name, no Exclude and the default Max bytes; change them with **Edit** on the entry.
|
|
50
50
|
Counting stops at 5,000 files or after 2 seconds and shows `5000+ files`, so picking a huge folder by mistake does not hang the menu.
|
|
51
51
|
|
|
52
52
|
An entry has:
|
|
53
53
|
|
|
54
54
|
| Field | Meaning |
|
|
55
55
|
| --- | --- |
|
|
56
|
-
| Name | 1 to 24 characters: a lowercase letter, then lowercase letters, digits or `_`. Defaults to the folder name (`
|
|
56
|
+
| Name | 1 to 24 characters: a lowercase letter, then lowercase letters, digits or `_`. Defaults to the folder name (`team.docs` becomes `team_docs`). It prefixes the tool names. |
|
|
57
57
|
| Docs folder | Absolute path of the folder that holds the markdown files. |
|
|
58
|
-
| Exclude | Folder names (`evidence`) or root-relative paths (`
|
|
58
|
+
| Exclude | Folder names (`evidence`) or root-relative paths (`guide/archive`) to skip. Folders starting with `.` and `node_modules` are always skipped. |
|
|
59
59
|
| Max bytes | Response size limit in UTF-8 bytes. Default 16000, minimum 4000. |
|
|
60
60
|
|
|
61
61
|
Symbolic links and junctions are not followed. librian only reads your docs; it never writes to them.
|
|
@@ -86,8 +86,8 @@ If `librian` is already registered there with a different command, Apply replace
|
|
|
86
86
|
### Runtime
|
|
87
87
|
|
|
88
88
|
librian installs itself with `npm install --prefix ~/.librian/runtime librian`, so the registered server does not depend on `npx` or a download at session start.
|
|
89
|
-
**Install**, **Check for updates** (asks npm only when you choose it) and **Update to X** do what they say; **Uninstall** removes the runtime folder and offers to unregister the services first.
|
|
90
|
-
Docs
|
|
89
|
+
**Install**, **Check for updates** (asks npm only when you choose it) and **Update to X** do what they say; **Uninstall** removes the runtime folder and `history.db` and offers to unregister the services first.
|
|
90
|
+
Docs folders and the catalog are kept.
|
|
91
91
|
|
|
92
92
|
### Where things live
|
|
93
93
|
|
|
@@ -95,20 +95,22 @@ Docs entries are kept.
|
|
|
95
95
|
| --- | --- |
|
|
96
96
|
| `~/.librian/catalog.json` | Your entries and which services are registered. No secrets. |
|
|
97
97
|
| `~/.librian/runtime/` | The installed package. |
|
|
98
|
+
| `~/.librian/history.db` | What `changes` compares against: per docs file, its heading lines and a short hash of each block. No docs text is stored. You can delete it; the next session starts a new history. |
|
|
98
99
|
|
|
99
100
|
Set `LIBRIAN_HOME` to use another folder. When it is not the default, the registered command carries it along.
|
|
100
101
|
|
|
101
102
|
## What the AI sees
|
|
102
103
|
|
|
103
|
-
One server,
|
|
104
|
+
One server, five tools per docs folder, prefixed with the entry name: for an entry `team` the tools are `team__list`, `team__outline`, `team__read`, `team__search` and `team__changes`.
|
|
104
105
|
Each tool description names its folder, and the server instructions list the folders with their file counts. A folder that is missing on disk offers no tools and is marked `unavailable`.
|
|
105
106
|
|
|
106
107
|
| Tool | Input | Returns |
|
|
107
108
|
| --- | --- | --- |
|
|
108
|
-
| `list` | `prefix?` | Files with size and document title, grouped by folder. `prefix` is a root-relative path start: `
|
|
109
|
+
| `list` | `prefix?` | Files with size and document title, grouped by folder. `prefix` is a root-relative path start: `guide/api` matches `guide/api/…` and `guide/api-notes.md`, `guide/api/` matches the folder only. |
|
|
109
110
|
| `outline` | `ref` | Headings of a file or of one section, each with its line range and size. |
|
|
110
111
|
| `read` | `ref` | The text of a whole file, one section or a line range. |
|
|
111
112
|
| `search` | `query`, `prefix?`, `limit?`, `offset?` | Blocks that contain every word of the query, each with its `path:start-end`, ancestor headings, size, number of hits and a one-line excerpt. |
|
|
113
|
+
| `changes` | `since?`, `prefix?`, `offset?` | Blocks added, changed or removed since the session start (or `since`), each with its current `path:start-end`, ancestor headings and size. Added and removed files are one line each. |
|
|
112
114
|
|
|
113
115
|
A typical session: `search` or `list` to find the file, `outline` to see its headings, `read` one section.
|
|
114
116
|
|
|
@@ -131,7 +133,30 @@ When you pass a reference to another agent or write it into a document, prefer `
|
|
|
131
133
|
- Words are separated by spaces; wrap a phrase in double quotes to keep it as one word. Matching ignores case.
|
|
132
134
|
- A word made only of letters, digits and `_` matches at the start of a word (`uat` matches `UAT` and `uat_token`, not `evaluate`). Other words, such as Korean, match anywhere.
|
|
133
135
|
- Every word must appear in the same block, a heading plus the text up to the next heading. Ancestor headings count, so a block under `## Release rail` matches `release deploy` even if only `deploy` is in its text.
|
|
134
|
-
- Results are ordered by words found in headings, then
|
|
136
|
+
- Results are ordered by words found in headings, then a relevance score that favours short, focused blocks over long ones that merely repeat a word (BM25), then path and line. The `N hits` on a row is the plain match count.
|
|
137
|
+
|
|
138
|
+
### Changes
|
|
139
|
+
|
|
140
|
+
`changes` tells an agent what moved in the docs while it worked, so it re-reads only that.
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
Changes since 2026-11-08T09:00:12.034+09:00 (session start) · 3 files · 4 blocks
|
|
144
|
+
As of 2026-11-08T11:30:05.678+09:00. Pass this as `since` to see only later changes.
|
|
145
|
+
|
|
146
|
+
guide/setup.md
|
|
147
|
+
changed guide/setup.md:41-58 · ## 3. Setup › ### 3.3 Pipes · 1.2K
|
|
148
|
+
added guide/setup.md:59-70 · ## 3. Setup › ### 3.4 Sockets · 640B
|
|
149
|
+
removed ## 3. Setup › ### 3.5 Legacy
|
|
150
|
+
team/decisions.md · added · 3.1K
|
|
151
|
+
old/notes.md · removed
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
- `since` is an ISO 8601 time with or without a zone (`2026-11-08T09:00:00+09:00`, `2026-11-08T09:00`; no zone means local time). Leave it out for the session start. A malformed value is an error with an example.
|
|
155
|
+
- Pass the `As of` time back as `since` to see only what changed after that call: no gaps, no repeats. While paging with `offset`, keep the same `since`.
|
|
156
|
+
- Blocks are paired by their heading line, in order, so a block that only moved down the file is not reported, repeated headings pair up in order, a renamed heading is `removed` plus `added`, and an edit that was undone is not reported. A block is a heading plus the text up to the next heading, the same unit `search` returns.
|
|
157
|
+
- Output stays within the byte limit and is cut between files (`More: offset=N`). A file whose own list does not fit becomes one line: `guide/setup.md · changed · 34 of 40 blocks; outline it`.
|
|
158
|
+
- A `since` older than the first record says where the history starts (`History starts …`) and uses that.
|
|
159
|
+
- The record is kept in `~/.librian/history.db` for 30 days, across restarts and shared by every session, and a running server also refreshes it every 5 minutes so the times stay close to the real edits. If the file cannot be used, only `changes` reports it.
|
|
135
160
|
|
|
136
161
|
### Limits and continuing
|
|
137
162
|
|
|
@@ -140,7 +165,7 @@ When something is bigger, the response says how to get the rest:
|
|
|
140
165
|
|
|
141
166
|
- `read` of a large file returns its outline; `read` of a large section with subsections returns the section's own text plus the subsection outline.
|
|
142
167
|
- `read` of a large section without subsections returns the first page and ends with `Continue: path:next-end`. Pass that reference to `read` to get the next page.
|
|
143
|
-
- `search` and `list` end with `More: offset=N` or a hint to narrow with `prefix`.
|
|
168
|
+
- `search`, `changes` and `list` end with `More: offset=N` or a hint to narrow with `prefix`.
|
|
144
169
|
|
|
145
170
|
## Advanced: one folder, registered by hand
|
|
146
171
|
|
|
@@ -171,6 +196,8 @@ librian --help | --version
|
|
|
171
196
|
|
|
172
197
|
## Contributing
|
|
173
198
|
|
|
199
|
+
See [README_DEV.md](README_DEV.md) for the build, the tests and the design.
|
|
200
|
+
|
|
174
201
|
To run a checkout of this repository instead of the published package, build it (`npm run build`) and install it into the runtime: `npm install --prefix ~/.librian/runtime <path to the checkout>`. The menu then shows the runtime as `linked to <path>`, and **Runtime → Install from npm** switches back.
|
|
175
202
|
|
|
176
203
|
## License
|