pi-weave 0.3.8 → 0.3.10
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 +21 -17
- package/package.json +4 -3
- package/skills/weave-explore/SKILL.md +3 -5
- package/skills/weave-notepad/SKILL.md +22 -2
- package/skills/weave-notepad/references/second-thoughts.md +57 -0
- package/src/core/graph/build.ts +1 -1
- package/src/core/graph/current.ts +10 -8
- package/src/core/history.ts +417 -0
- package/src/core/index.ts +19 -0
- package/src/core/links/repair.ts +5 -68
- package/src/core/noteAction.ts +72 -2
- package/src/core/openInEditor.ts +3 -8
- package/src/core/repoAction.ts +20 -61
- package/src/core/repoIndex.ts +38 -0
- package/src/core/trail.ts +124 -0
- package/src/core/types.ts +1 -3
- package/src/core/vault.ts +116 -29
- package/src/core/view/focus.ts +2 -2
- package/src/core/view/index.ts +2 -3
- package/src/core/view/rawTail.ts +153 -0
- package/src/core/workspace.ts +20 -26
- package/src/core/workspaceCommands.ts +14 -14
- package/src/opencode/tools.ts +3 -3
- package/src/opencode/tui.ts +1 -7
- package/src/pi/index.ts +68 -80
- package/src/pi/tools/noteTool.ts +1 -1
- package/src/pi/tools/repoTool.ts +3 -6
- package/src/pi/viewer/web/run.ts +6 -8
- package/src/web/client/api.ts +103 -5
- package/src/web/client/context/context.model.ts +5 -0
- package/src/web/client/dist/app.js +499 -129
- package/src/web/client/graph/Graph.tsx +166 -14
- package/src/web/client/graph/column.model.ts +59 -2
- package/src/web/client/graph/graph.model.ts +183 -7
- package/src/web/client/graph/renderer.ts +39 -9
- package/src/web/client/graph/spotlight.model.ts +472 -0
- package/src/web/client/note/Note.tsx +370 -66
- package/src/web/client/note/Replay.tsx +139 -0
- package/src/web/client/note/drafts.ts +115 -11
- package/src/web/client/note/editbar.model.ts +153 -0
- package/src/web/client/note/note.model.ts +82 -1
- package/src/web/client/note/replay.model.ts +248 -0
- package/src/web/client/search/SearchPalette.tsx +103 -34
- package/src/web/client/search/search.model.ts +533 -26
- package/src/web/client/shell/ContextRail.tsx +7 -0
- package/src/web/client/shell/Settings.tsx +21 -1
- package/src/web/client/shell/Shell.tsx +93 -27
- package/src/web/client/shell/StatusBar.tsx +1 -0
- package/src/web/client/shell/icons.model.ts +68 -1
- package/src/web/client/shell/keys.model.ts +31 -8
- package/src/web/client/shell/shell.model.ts +48 -1
- package/src/web/client/shell/theme.model.ts +3 -0
- package/src/web/client/shell/theme.ts +354 -32
- package/src/web/client/shell/workspace.css.ts +40 -9
- package/src/web/client/trail/TrailStrip.tsx +55 -0
- package/src/web/client/trail/trail.model.ts +195 -0
- package/src/web/client/trail/trail.ts +45 -0
- package/src/web/client/tree/Tree.tsx +7 -3
- package/src/web/client/tree/tree.model.ts +2 -5
- package/src/web/server/page.ts +1 -1
- package/src/web/server/routes.ts +83 -3
- package/src/web/shared/logo.ts +1 -1
- package/src/web/shared/themes.ts +1 -1
- package/src/web/shared/view.ts +10 -4
- package/src/web/shared/wire.ts +74 -1
- package/src/web/shared/workspace.ts +10 -2
- package/src/core/view/health.ts +0 -160
- package/src/pi/viewer/tui/bodyStore.ts +0 -95
- package/src/pi/viewer/tui/branding.ts +0 -14
- package/src/pi/viewer/tui/model.ts +0 -390
- package/src/pi/viewer/tui/openNote.ts +0 -11
- package/src/pi/viewer/tui/run.ts +0 -71
- package/src/pi/viewer/tui/surface/base.ts +0 -203
- package/src/pi/viewer/tui/surface/detail.ts +0 -315
- package/src/pi/viewer/tui/surface/explore.ts +0 -241
- package/src/pi/viewer/tui/surface/focus.ts +0 -139
- package/src/pi/viewer/tui/surface/health.ts +0 -102
- package/src/pi/viewer/tui/theme.ts +0 -90
- package/src/pi/viewer/tui/workspace.ts +0 -53
- package/src/pi/viewer/tui/workspaceRoot.ts +0 -389
package/README.md
CHANGED
|
@@ -113,7 +113,7 @@ You: Start a note for this interview. I’m going to narrate; keep my words
|
|
|
113
113
|
|
|
114
114
|
For each chunk, the agent:
|
|
115
115
|
|
|
116
|
-
1. appends your words unchanged to the note’s `## Raw` tail;
|
|
116
|
+
1. appends your words unchanged to the note’s `## Raw` tail, starting with the very first chunk;
|
|
117
117
|
2. refreshes the structured summary above it;
|
|
118
118
|
3. leaves the raw record untouched.
|
|
119
119
|
|
|
@@ -152,20 +152,25 @@ Renaming or moving a note rewrites its inbound links automatically, so its backl
|
|
|
152
152
|
|
|
153
153
|
```bash
|
|
154
154
|
/weave-view # open the browser workspace
|
|
155
|
-
/weave-view --no-open # start it and print the URL
|
|
156
|
-
/weave-view tui # Pi only: terminal UI for SSH or browser-free use
|
|
155
|
+
/weave-view --no-open # start it and print the URL (handy over SSH)
|
|
157
156
|
```
|
|
158
157
|
|
|
159
158
|
Browse and search your notes, follow links, or explore the graph. Use tabs and split panes to keep related notes side by side.
|
|
160
159
|
Notes update within a couple of seconds as your agent writes them.
|
|
160
|
+
While your agent works, the notes it searches, reads, and writes light up in the tree and graph, and fade after about a minute.
|
|
161
|
+
The **This turn** list in the Context card shows those steps in order; click an earlier turn to replay it. Context floats over the page's
|
|
162
|
+
right margin: fold it with `]`, or pin it to dock it as a column.
|
|
163
|
+
In search, `Tab` switches between notes, code, and tags, and `⇧↵` lights every result up in the graph.
|
|
161
164
|
|
|
162
165
|
Ask your agent to write, organize, and connect notes, or click **New note** on an empty tab to start one yourself.
|
|
163
|
-
Click **Edit** to change Markdown
|
|
166
|
+
Click **Edit** to change Markdown. Edits save themselves after a short pause (or `⌘S` / `Ctrl S` right away), and **Done** closes the
|
|
167
|
+
editor. Your original words in `## Raw` stay intact.
|
|
164
168
|
Tabs, layout, and settings restore when you return and survive package updates for the same vault and repository;
|
|
165
169
|
unsaved drafts last only while the browser stays open.
|
|
166
170
|
|
|
167
171
|
Use **Settings** for themes, fonts, layout, and a manual vault ZIP backup. Press `?` for keyboard shortcuts.
|
|
168
|
-
|
|
172
|
+
|
|
173
|
+
Every change to a note is saved to `<vault>/history/`, whether you, your agent, or another editor made it. Press **History** on a note and drag the slider (or press play) to watch it being written, Raw tail included. Turn this off in **Settings → Editor → Note history**.
|
|
169
174
|
|
|
170
175
|
## Remember sessions
|
|
171
176
|
|
|
@@ -182,18 +187,18 @@ technical takeaways, works outside Git repositories, and can be stopped with `/w
|
|
|
182
187
|
|
|
183
188
|
## Repository knowledge
|
|
184
189
|
|
|
185
|
-
Inside a Git repository,
|
|
190
|
+
Inside a Git repository, `/weave-scan` asks your session model for a short summary of each file, so you and your agent can find your way
|
|
191
|
+
around without reading everything. It only revisits files whose content changed since the last run.
|
|
186
192
|
|
|
187
193
|
```bash
|
|
188
|
-
/weave-scan #
|
|
189
|
-
/weave-scan deep # also summarize changed files with the active model
|
|
194
|
+
/weave-scan # summarize changed files with the active model
|
|
190
195
|
```
|
|
191
196
|
|
|
192
|
-
|
|
193
|
-
|
|
197
|
+
pi-weave also keeps a small structural index of the repository (languages, packages, modules, entry points, Git state). It feeds the graph
|
|
198
|
+
and links notes to the files they mention. You never build it by hand: it is refreshed automatically whenever something needs it.
|
|
194
199
|
|
|
195
|
-
|
|
196
|
-
|
|
200
|
+
Everything under `<repo>/.okf/` is a cache, not a source of truth. Delete it and nothing important is lost. pi-weave excludes it locally
|
|
201
|
+
from Git by default.
|
|
197
202
|
|
|
198
203
|
## Commands and tools
|
|
199
204
|
|
|
@@ -201,14 +206,13 @@ Most people only need natural language and `/weave-view`.
|
|
|
201
206
|
|
|
202
207
|
| Surface | Name | Purpose |
|
|
203
208
|
|---|---|---|
|
|
204
|
-
| Command | `/weave-view` | Open the browser workspace
|
|
209
|
+
| Command | `/weave-view` | Open the browser workspace |
|
|
205
210
|
| Command | `/weave` | Show vault and repository status |
|
|
206
|
-
| Command | `/weave-scan` |
|
|
207
|
-
| Command | `/weave-scan deep` | Add incremental model-written file summaries |
|
|
211
|
+
| Command | `/weave-scan` | Add incremental model-written file summaries |
|
|
208
212
|
| Command | `/weave-scan sessions [path]` | Turn changed session-history files into durable memory notes |
|
|
209
|
-
| Command | `/weave-scan-cancel` | Stop a
|
|
213
|
+
| Command | `/weave-scan-cancel` | Stop a running scan |
|
|
210
214
|
| Tool | `weave_note` | List, read, add, append, finalize, and search notes |
|
|
211
|
-
| Tool | `weave_repo` |
|
|
215
|
+
| Tool | `weave_repo` | Describe the repository structure for the agent |
|
|
212
216
|
|
|
213
217
|
The included `weave-notepad` and `weave-explore` skills teach Pi and OpenCode when and how to use these tools. In OpenCode, `/weave` shows
|
|
214
218
|
vault/repository status and scan progress appears in toasts; Pi keeps its persistent status line. V1 slash commands use its standard prompt
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-weave",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.10",
|
|
4
4
|
"description": "Local-first Markdown memory and knowledge graph for Pi and OpenCode: preserve decisions, recall sessions, and explore notes with code.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.web.json",
|
|
60
60
|
"build:web": "node scripts/build-web.mjs",
|
|
61
61
|
"build:web:check": "node scripts/build-web.mjs --check",
|
|
62
|
+
"e2e": "vitest run --config vitest.e2e.config.ts",
|
|
62
63
|
"check": "npm run typecheck && npm run build:web:check && npm run coverage",
|
|
63
64
|
"eval:notepad": "node scripts/eval-notepad-search.mjs",
|
|
64
65
|
"rewrap:md": "node scripts/rewrap-md.mjs",
|
|
@@ -68,14 +69,13 @@
|
|
|
68
69
|
"peerDependencies": {
|
|
69
70
|
"@earendil-works/pi-ai": "*",
|
|
70
71
|
"@earendil-works/pi-coding-agent": "*",
|
|
71
|
-
"@earendil-works/pi-tui": "*",
|
|
72
72
|
"typebox": "*"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
75
|
"@earendil-works/pi-ai": "^0.84.2",
|
|
76
76
|
"@earendil-works/pi-coding-agent": "^0.84.2",
|
|
77
|
-
"@earendil-works/pi-tui": "^0.84.2",
|
|
78
77
|
"@opencode-ai/plugin": "1.18.29",
|
|
78
|
+
"@opencode-ai/sdk": "1.18.29",
|
|
79
79
|
"@opencode/plugin": "^2.0.19",
|
|
80
80
|
"@types/d3-force": "^3.0.10",
|
|
81
81
|
"@types/node": "^24.0.0",
|
|
@@ -86,6 +86,7 @@
|
|
|
86
86
|
"graphology": "^0.26.0",
|
|
87
87
|
"graphology-types": "^0.24.8",
|
|
88
88
|
"marked": "^18.0.10",
|
|
89
|
+
"playwright-core": "1.56.1",
|
|
89
90
|
"preact": "^10.29.8",
|
|
90
91
|
"sigma": "^3.0.3",
|
|
91
92
|
"typebox": "1.3.7",
|
|
@@ -9,17 +9,15 @@ Use `weave_repo`. Without the tool, read `<repo>/.okf/` directly. The index is a
|
|
|
9
9
|
|
|
10
10
|
## Workflow
|
|
11
11
|
|
|
12
|
-
1.
|
|
13
|
-
`action=overview`.
|
|
12
|
+
1. Read `action=overview`. It builds or refreshes the structure index itself, so there is nothing to scan first.
|
|
14
13
|
2. Use the overview's languages, packages, modules, and entry points to select relevant paths instead of listing the whole repository.
|
|
15
14
|
3. Read available `.okf/repository/summaries/` sidecars before opening full files.
|
|
16
15
|
4. Inspect the relevant code and cite indexed paths in your answer.
|
|
17
16
|
|
|
18
17
|
## Commands
|
|
19
18
|
|
|
20
|
-
- `/weave-scan`
|
|
21
|
-
|
|
22
|
-
implicitly. Only changed content is summarized again.
|
|
19
|
+
- `/weave-scan` generates file summaries using the session model. Offer it when summaries would help and the overview shows none;
|
|
20
|
+
never run it implicitly. Only changed content is summarized again.
|
|
23
21
|
- `/weave-view` opens the browser workspace.
|
|
24
22
|
- `/weave-scan sessions [path]` writes session memories to the vault, not the repository index; see `weave-notepad`.
|
|
25
23
|
|
|
@@ -26,7 +26,8 @@ Use `weave_note`. Without the tool, edit the files directly (`PI_WEAVE_VAULT` ov
|
|
|
26
26
|
|
|
27
27
|
During live dictation or interviews, keep the organized note current after every append; do not wait until the session ends:
|
|
28
28
|
|
|
29
|
-
1. `
|
|
29
|
+
1. Start the note with `add` and `raw: true`, so its first words land in `## Raw` too. Then `append` each chunk with `raw: true`.
|
|
30
|
+
Never silently reword dictation.
|
|
30
31
|
2. Immediately `finalize` the body above the tail: TLDR, sections, decisions, questions, tasks, entities, and links reflecting
|
|
31
32
|
everything said so far.
|
|
32
33
|
|
|
@@ -36,7 +37,7 @@ Outside dictation, finalize only on request.
|
|
|
36
37
|
|
|
37
38
|
- Keep an append-only raw section at the bottom: `---`, then `## Raw`, then the notice shown below.
|
|
38
39
|
- Fence verbatim input in code blocks. Prepend each subsequent block with `<!-- appended YYYY-MM-DD HH:MM -->`.
|
|
39
|
-
- Use `append` with `raw: true` when available;
|
|
40
|
+
- Use `add` or `append` with `raw: true` when available; they maintain this format and create the tail if missing. Do not hand-format it.
|
|
40
41
|
- `finalize` changes only the body above the tail. Never rewrite, remove, or move words out of the raw tail. If no tail exists, preserve the
|
|
41
42
|
entire previous body as a new raw tail before restructuring; the tool does this automatically.
|
|
42
43
|
|
|
@@ -58,6 +59,25 @@ When editing files directly, preserve the same format:
|
|
|
58
59
|
```
|
|
59
60
|
````
|
|
60
61
|
|
|
62
|
+
## Second thoughts
|
|
63
|
+
|
|
64
|
+
When the user states a decision, check the `search` hits you already made and the target note's decisions for an earlier **human**
|
|
65
|
+
decision that it contradicts. Do not run extra searches or reads for this.
|
|
66
|
+
|
|
67
|
+
- Keep the bar high: an explicit decision against an explicit decision on the same subject. Overlapping facts, refinements, and
|
|
68
|
+
compatible choices are not conflicts. When unsure, stay silent.
|
|
69
|
+
- Capture first, then ask. Save the user's words as usual, then ask one short question quoting the earlier decision with its date and
|
|
70
|
+
slug: replace it, or are both true? At most one question per turn.
|
|
71
|
+
- `source` is per note, not per line, so judge each decision by where it came from. It is human when the user's words for it are in the
|
|
72
|
+
raw tail, or when it sits in a `source: human` note outside an "Agent addendum". Anything else counts as agent.
|
|
73
|
+
- Conflicting agent or `generated` decisions do not get a question; the human statement already wins. Mention them in one line.
|
|
74
|
+
- If the user says it replaces the old one, strike the old decision through instead of deleting it, and link the new one:
|
|
75
|
+
`~~OIDC next quarter~~ (superseded 2026-10-11 → [[auth-sso]])`, where the link names the note that holds the new decision. When the
|
|
76
|
+
new decision is in the same note, drop the link: `(superseded 2026-10-11)`. A note should not link to itself.
|
|
77
|
+
- Never edit the raw tail to supersede anything. `finalize` keeps superseded lines, struck through, in the body.
|
|
78
|
+
|
|
79
|
+
See [references/second-thoughts.md](references/second-thoughts.md) for example exchanges.
|
|
80
|
+
|
|
61
81
|
## TLDR on finalize
|
|
62
82
|
|
|
63
83
|
Every finalized note opens with a TLDR directly under the title: a `**TLDR:**` block of 1–8 lines on what the note says and what
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Second thoughts
|
|
2
|
+
|
|
3
|
+
Catch a decision that contradicts an earlier human decision while the user is there to answer in one word. Silence is the default; a
|
|
4
|
+
false alarm costs more than a missed one.
|
|
5
|
+
|
|
6
|
+
## Conflict: ask once, after saving
|
|
7
|
+
|
|
8
|
+
```text
|
|
9
|
+
User: Add to the auth note that we're going with SAML.
|
|
10
|
+
|
|
11
|
+
Agent: (search "auth" → auth-migration; Decisions has "2026-09-03: OIDC next quarter, JWT compatibility window", source: human)
|
|
12
|
+
(append to auth-migration)
|
|
13
|
+
|
|
14
|
+
Agent: Added. One thing: on Sep 3 you decided "OIDC next quarter, JWT compatibility window" (auth-migration, Decisions).
|
|
15
|
+
Should SAML replace that decision, or are both true?
|
|
16
|
+
|
|
17
|
+
User: Replace it.
|
|
18
|
+
|
|
19
|
+
Agent: (edit the body above the raw tail)
|
|
20
|
+
Updated. The Sep 3 decision is now marked superseded.
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The Decisions section afterwards:
|
|
24
|
+
|
|
25
|
+
```markdown
|
|
26
|
+
## Decisions
|
|
27
|
+
|
|
28
|
+
- ~~2026-09-03: OIDC next quarter, JWT compatibility window~~ (superseded 2026-10-11)
|
|
29
|
+
- 2026-10-11: Go with SAML.
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The new decision is in the same note, so there is no link. When it lives in another note, link it:
|
|
33
|
+
`(superseded 2026-10-11 → [[auth-sso]])`.
|
|
34
|
+
|
|
35
|
+
If the user answers "both are true", leave both lines as they are and say so.
|
|
36
|
+
|
|
37
|
+
## No question
|
|
38
|
+
|
|
39
|
+
| New statement | Earlier note | Why silent |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| "Use SAML for the admin portal" | human: "OIDC for the customer app" | Different subjects |
|
|
42
|
+
| "Use Okta as the OIDC provider" | human: "OIDC next quarter" | Compatible; it builds on the decision |
|
|
43
|
+
| "We're going with SAML" | generated session note: "team leaning OIDC" | Not a human decision; mention it in one line |
|
|
44
|
+
| "SAML might be simpler" | human: "OIDC next quarter" | Not a decision |
|
|
45
|
+
| "We're going with SAML" | "OIDC next quarter" in the Agent addendum of a `source: human` note | Agent-written line; mention it in one line |
|
|
46
|
+
|
|
47
|
+
## Mixed authorship
|
|
48
|
+
|
|
49
|
+
`source` describes who created the note, not each line in it. A decision the user dictated into an agent note is human: its words are in
|
|
50
|
+
the raw tail. A decision in the Agent addendum of a human note is the agent's. Check the raw tail or the addendum before deciding whether to
|
|
51
|
+
ask.
|
|
52
|
+
|
|
53
|
+
## Rules of thumb
|
|
54
|
+
|
|
55
|
+
- Use the hits from the one `search` the capture already made; no extra calls to look for conflicts.
|
|
56
|
+
- At most one question per turn, even if several decisions conflict. Name the strongest; mention others in the same question.
|
|
57
|
+
- Never delete the old decision and never touch the raw tail. Superseded lines survive `finalize`, struck through.
|
package/src/core/graph/build.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import type { HtmlArtifact, Note, RepoIndex, StalenessReport, VaultStatus } from "../types";
|
|
12
12
|
import { createHash } from "node:crypto";
|
|
13
13
|
import type { SummaryRecord } from "../summaries";
|
|
14
|
-
import type {
|
|
14
|
+
import type { GraphEdge, GraphModel, GraphNode } from "./model";
|
|
15
15
|
import { buildPathIndex, resolveMentions, type PathIndex } from "./mentions";
|
|
16
16
|
import { extractWikilinks } from "./wikilinks";
|
|
17
17
|
|
|
@@ -15,7 +15,7 @@ import { join, resolve, sep } from "node:path";
|
|
|
15
15
|
// that cache, so going through the barrel would close an import cycle.
|
|
16
16
|
import { findGitRoot } from "../git";
|
|
17
17
|
import { resolveVaultRoot } from "../paths";
|
|
18
|
-
import {
|
|
18
|
+
import { ensureRepoIndex } from "../repoIndex";
|
|
19
19
|
import { readSummaryMap } from "../summaries";
|
|
20
20
|
import type { Note } from "../types";
|
|
21
21
|
import { getNote, readVault, resolveNotePath } from "../vault";
|
|
@@ -72,7 +72,7 @@ export async function readOkfFileForView(cwd: string, rel: string): Promise<{ pa
|
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
74
|
* Assemble the repository half of the graph input for `cwd`, or null when
|
|
75
|
-
* cwd is not inside a git repository with
|
|
75
|
+
* cwd is not inside a git repository with at least one commit. Shared
|
|
76
76
|
* with `src/core/cache/workspace` so the cached and uncached paths cannot
|
|
77
77
|
* drift in what they read.
|
|
78
78
|
*/
|
|
@@ -81,19 +81,21 @@ export async function readRepositorySide(
|
|
|
81
81
|
): Promise<Pick<BuildGraphInput, "repository" | "summaries"> | null> {
|
|
82
82
|
const repoRoot = await findGitRoot(cwd);
|
|
83
83
|
if (repoRoot === null) return null;
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
// The structure index is plumbing: built or refreshed here when missing or
|
|
85
|
+
// stale, so the repository side of the graph never waits on a manual scan.
|
|
86
|
+
const repository = await ensureRepoIndex(repoRoot);
|
|
87
|
+
if (repository === null) return null;
|
|
86
88
|
return {
|
|
87
|
-
repository
|
|
89
|
+
repository,
|
|
88
90
|
summaries: await readSummaryMap(repoRoot), // deep-scan sidecars, read live
|
|
89
91
|
};
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
/**
|
|
93
95
|
* Assemble the fresh graph from disk. Called on every viewer fetch
|
|
94
|
-
* (no caching). Reads the complete vault and, when cwd is
|
|
95
|
-
* repository, the repo index + deep-scan summary
|
|
96
|
-
*
|
|
96
|
+
* (no caching). Reads the complete vault and, when cwd is inside a git
|
|
97
|
+
* repository, the repo index (refreshed on demand) + deep-scan summary
|
|
98
|
+
* sidecars. Degrades to a vault-only graph when the repo has no commits.
|
|
97
99
|
*
|
|
98
100
|
* One read per note: `readVault` returns bodies *and* the file count, so the
|
|
99
101
|
* old `listNotes` → `getNote`-per-slug → `noteCount` sequence (2N reads plus
|