pi-weave 0.2.3 → 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 +40 -21
- package/package.json +22 -5
- package/skills/weave-explore/SKILL.md +17 -33
- package/skills/weave-notepad/SKILL.md +57 -109
- package/skills/weave-notepad/references/link-repair.md +25 -73
- package/src/core/index.ts +27 -1
- package/src/core/links/similar.ts +97 -30
- package/src/core/noteAction.ts +343 -0
- package/src/core/repoAction.ts +84 -0
- package/src/core/sessions.ts +80 -1
- package/src/core/summaries.ts +16 -0
- package/src/core/vault.ts +78 -6
- package/src/core/workspace.ts +1 -1
- package/src/core/workspaceCommands.ts +227 -0
- package/src/opencode/commands.ts +138 -0
- package/src/opencode/index.ts +88 -0
- package/src/opencode/rpc.ts +37 -0
- package/src/opencode/tools.ts +43 -0
- package/src/opencode/tui.ts +96 -0
- package/src/opencode/v1.ts +161 -0
- package/src/pi/sessionScan.ts +4 -28
- package/src/pi/summarize.ts +10 -25
- package/src/pi/tools/noteTool.ts +8 -296
- package/src/pi/tools/repoTool.ts +8 -75
- package/src/pi/viewer/web/run.ts +16 -77
- package/src/web/client/dist/app.js +13 -13
- package/src/web/client/graph/graph.model.ts +6 -4
- package/src/web/server/controller.ts +79 -0
package/README.md
CHANGED
|
@@ -53,14 +53,24 @@ pi-weave keeps track of where knowledge came from, while making the whole worksp
|
|
|
53
53
|
|
|
54
54
|
**The conversation can end. The knowledge doesn't have to.**
|
|
55
55
|
|
|
56
|
-
##
|
|
56
|
+
## Install
|
|
57
57
|
|
|
58
|
-
pi-weave
|
|
58
|
+
pi-weave supports [Pi](https://github.com/earendil-works/pi) and OpenCode (V1 **1.18.29+** and V2) from the same package. The adapters share
|
|
59
|
+
the vault, repository index, browser workspace, tools, and skills.
|
|
59
60
|
|
|
60
|
-
|
|
61
|
-
become the product itself, and its extensibility makes projects like pi-weave possible.
|
|
61
|
+
OpenCode V2:
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
```bash
|
|
64
|
+
opencode plugin add pi-weave
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
OpenCode V1 1.18.29+: add the package to both `opencode.json` (server) and `tui.json` (browser opening):
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{ "plugin": ["pi-weave"] }
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Pi:
|
|
64
74
|
|
|
65
75
|
```bash
|
|
66
76
|
pi install npm:pi-weave
|
|
@@ -75,7 +85,7 @@ pi install /path/to/pi-weave
|
|
|
75
85
|
|
|
76
86
|
Requires Node **20.13 or newer**.
|
|
77
87
|
|
|
78
|
-
Then just talk to
|
|
88
|
+
Then just talk to your agent.
|
|
79
89
|
|
|
80
90
|
## Start taking notes
|
|
81
91
|
|
|
@@ -92,21 +102,21 @@ You: Add that the gateway team owns the migration plan.
|
|
|
92
102
|
You: What open questions are in this note?
|
|
93
103
|
```
|
|
94
104
|
|
|
95
|
-
For live narration or interview notes, tell
|
|
105
|
+
For live narration or interview notes, tell your agent that you are dictating:
|
|
96
106
|
|
|
97
107
|
```text
|
|
98
108
|
You: Start a note for this interview. I’m going to narrate; keep my words
|
|
99
109
|
verbatim and organize the note as we go.
|
|
100
110
|
```
|
|
101
111
|
|
|
102
|
-
For each chunk,
|
|
112
|
+
For each chunk, the agent:
|
|
103
113
|
|
|
104
114
|
1. appends your words unchanged to the note’s `## Raw` tail;
|
|
105
115
|
2. refreshes the structured summary above it;
|
|
106
116
|
3. leaves the raw record untouched.
|
|
107
117
|
|
|
108
118
|
This makes the note readable during the conversation without replacing your words with an AI reconstruction. Notes based on your dictation
|
|
109
|
-
remain marked `source: human`; notes drafted by
|
|
119
|
+
remain marked `source: human`; notes drafted by the agent are marked `source: agent`.
|
|
110
120
|
|
|
111
121
|
Useful requests include:
|
|
112
122
|
|
|
@@ -141,7 +151,7 @@ Renaming or moving a note rewrites its inbound links automatically, so its backl
|
|
|
141
151
|
```bash
|
|
142
152
|
/weave-view # open the browser workspace
|
|
143
153
|
/weave-view --no-open # start it and print the URL
|
|
144
|
-
/weave-view tui # terminal UI for SSH or browser-free use
|
|
154
|
+
/weave-view tui # Pi only: terminal UI for SSH or browser-free use
|
|
145
155
|
```
|
|
146
156
|
|
|
147
157
|
The browser workspace has four connected views:
|
|
@@ -163,17 +173,18 @@ last writer wins, and the workspace picks up outside changes within a couple of
|
|
|
163
173
|
|
|
164
174
|
`/weave-view tui` is the smaller, read-only terminal explorer: tree, focused neighborhood, details, and link health over the same graph.
|
|
165
175
|
|
|
166
|
-
## Remember
|
|
176
|
+
## Remember sessions
|
|
167
177
|
|
|
168
178
|
```bash
|
|
169
|
-
/weave-scan sessions #
|
|
179
|
+
/weave-scan sessions # Pi history, or the current OpenCode session
|
|
170
180
|
/weave-scan sessions /path/to/history # explicit history root
|
|
171
181
|
```
|
|
172
182
|
|
|
173
183
|
This opt-in scan treats a supplied file—or every bounded text file under a supplied directory—as opaque session material for the active
|
|
174
|
-
model to interpret, then writes generated notes under `~/.okf/notes/sessions/`.
|
|
175
|
-
|
|
176
|
-
|
|
184
|
+
model to interpret, then writes generated notes under `~/.okf/notes/sessions/`. In OpenCode, the pathless form reads the current session
|
|
185
|
+
through the public plugin API; it never inspects OpenCode's internal database. That makes explicit paths usable with Claude Code, OpenCode,
|
|
186
|
+
Codex, or exported history trees without requiring their schema or file extension. It skips unchanged files, captures outcomes plus reusable
|
|
187
|
+
technical takeaways, works outside Git repositories, and can be stopped with `/weave-scan-cancel`.
|
|
177
188
|
|
|
178
189
|
## Repository knowledge
|
|
179
190
|
|
|
@@ -196,7 +207,7 @@ Most people only need natural language and `/weave-view`.
|
|
|
196
207
|
|
|
197
208
|
| Surface | Name | Purpose |
|
|
198
209
|
|---|---|---|
|
|
199
|
-
| Command | `/weave-view` | Open the browser
|
|
210
|
+
| Command | `/weave-view` | Open the browser workspace (`tui` is a Pi-only argument) |
|
|
200
211
|
| Command | `/weave` | Show vault and repository status |
|
|
201
212
|
| Command | `/weave-scan` | Build or refresh the repository index |
|
|
202
213
|
| Command | `/weave-scan deep` | Add incremental model-written file summaries |
|
|
@@ -205,7 +216,11 @@ Most people only need natural language and `/weave-view`.
|
|
|
205
216
|
| Tool | `weave_note` | List, read, add, append, finalize, and search notes |
|
|
206
217
|
| Tool | `weave_repo` | Check, scan, and summarize the repository index |
|
|
207
218
|
|
|
208
|
-
The included `weave-notepad` and `weave-explore` skills teach Pi when and how to use these tools.
|
|
219
|
+
The included `weave-notepad` and `weave-explore` skills teach Pi and OpenCode when and how to use these tools. In OpenCode, `/weave` shows
|
|
220
|
+
vault/repository status and scan progress appears in toasts; Pi keeps its persistent status line. V1 slash commands use its standard prompt
|
|
221
|
+
pipeline, so the model reports command results in the conversation. `/weave` does not open a dialog. V1 scans use the model from your last
|
|
222
|
+
chat message: send a message after selecting a model, then scan. Generation runs in temporary child sessions with tools denied;
|
|
223
|
+
those sessions are removed on completion or cancellation. V2 uses its direct command and generation APIs.
|
|
209
224
|
|
|
210
225
|
## Files, privacy, and portability
|
|
211
226
|
|
|
@@ -245,14 +260,18 @@ We probably want OIDC next quarter…
|
|
|
245
260
|
|
|
246
261
|
Set `PI_WEAVE_VAULT` to use a different vault location.
|
|
247
262
|
|
|
248
|
-
Reading, writing, searching, and viewing notes are local operations. Deep repository scans and session summaries send bounded input to
|
|
249
|
-
|
|
250
|
-
|
|
263
|
+
Reading, writing, searching, and viewing notes are local operations. Deep repository scans and session summaries send bounded input to the
|
|
264
|
+
active Pi/V2 model or the last-used V1 chat model. The browser workspace binds only to loopback, uses a per-session token, and shuts down
|
|
265
|
+
with the plugin lifecycle. OpenCode opens it automatically when the terminal can reach the viewer's loopback URL. Otherwise, it shows the
|
|
266
|
+
exact URL for a browser or tunnel.
|
|
251
267
|
|
|
252
|
-
The vault format, repository index, and skills are intentionally harness-agnostic. `src/core` contains no
|
|
268
|
+
The vault format, repository index, and skills are intentionally harness-agnostic. `src/core` contains no Pi- or OpenCode-specific imports.
|
|
253
269
|
|
|
254
270
|
## Development
|
|
255
271
|
|
|
272
|
+
The OpenCode V1/V2 bindings share tool schemas, core actions, and one command/scan workflow. Zod is the only direct runtime dependency,
|
|
273
|
+
required by V1's tool-schema protocol; OpenCode SDKs are development-only.
|
|
274
|
+
|
|
256
275
|
```bash
|
|
257
276
|
npm install
|
|
258
277
|
npm run check
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-weave",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.3.0",
|
|
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,
|
|
7
7
|
"publishConfig": {
|
|
@@ -9,10 +9,17 @@
|
|
|
9
9
|
},
|
|
10
10
|
"keywords": [
|
|
11
11
|
"pi-package",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
12
|
+
"pi-coding-agent",
|
|
13
|
+
"opencode-plugin",
|
|
14
|
+
"agent-memory",
|
|
15
|
+
"persistent-memory",
|
|
16
|
+
"markdown",
|
|
14
17
|
"notepad",
|
|
15
|
-
"
|
|
18
|
+
"local-first",
|
|
19
|
+
"knowledge-graph",
|
|
20
|
+
"codebase-memory",
|
|
21
|
+
"obsidian",
|
|
22
|
+
"developer-tools"
|
|
16
23
|
],
|
|
17
24
|
"license": "MIT",
|
|
18
25
|
"author": "Eran Yonai <yonai.eran@gmail.com>",
|
|
@@ -26,6 +33,10 @@
|
|
|
26
33
|
"node": ">=20.13.0"
|
|
27
34
|
},
|
|
28
35
|
"exports": {
|
|
36
|
+
"./server": "./src/opencode/index.ts",
|
|
37
|
+
".": "./src/opencode/index.ts",
|
|
38
|
+
"./tui": "./src/opencode/tui.ts",
|
|
39
|
+
"./rpc": "./src/opencode/rpc.ts",
|
|
29
40
|
"./core": "./src/core/index.ts"
|
|
30
41
|
},
|
|
31
42
|
"files": [
|
|
@@ -50,6 +61,7 @@
|
|
|
50
61
|
"build:web": "node scripts/build-web.mjs",
|
|
51
62
|
"build:web:check": "node scripts/build-web.mjs --check",
|
|
52
63
|
"check": "npm run typecheck && npm run build:web:check && npm run coverage",
|
|
64
|
+
"eval:notepad": "node scripts/eval-notepad-search.mjs",
|
|
53
65
|
"rewrap:md": "node scripts/rewrap-md.mjs",
|
|
54
66
|
"rewrap:md:check": "node scripts/rewrap-md.mjs --check",
|
|
55
67
|
"prepublishOnly": "npm run check"
|
|
@@ -64,6 +76,8 @@
|
|
|
64
76
|
"@earendil-works/pi-ai": "^0.84.2",
|
|
65
77
|
"@earendil-works/pi-coding-agent": "^0.84.2",
|
|
66
78
|
"@earendil-works/pi-tui": "^0.84.2",
|
|
79
|
+
"@opencode-ai/plugin": "1.18.29",
|
|
80
|
+
"@opencode/plugin": "^2.0.19",
|
|
67
81
|
"@types/d3-force": "^3.0.10",
|
|
68
82
|
"@types/node": "^24.0.0",
|
|
69
83
|
"@vitest/coverage-v8": "^3.2.4",
|
|
@@ -78,5 +92,8 @@
|
|
|
78
92
|
"typebox": "1.3.7",
|
|
79
93
|
"typescript": "^5.8.0",
|
|
80
94
|
"vitest": "^3.2.4"
|
|
95
|
+
},
|
|
96
|
+
"dependencies": {
|
|
97
|
+
"zod": "4.1.8"
|
|
81
98
|
}
|
|
82
99
|
}
|
|
@@ -1,54 +1,38 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: weave-explore
|
|
3
|
-
description: Explore
|
|
3
|
+
description: Explore unfamiliar git repositories and answer structural questions about modules, packages, or architecture using the pi-weave index (.okf).
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Weave Explore
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
cache. Deleting `.okf` loses nothing — rescan to regenerate it.
|
|
10
|
-
|
|
11
|
-
## Tools
|
|
12
|
-
|
|
13
|
-
In pi, use the `weave_repo` tool (or the `/weave-scan` command). To see the assembled graph in the terminal, run `/weave-view tui` (Explore
|
|
14
|
-
tree, Focus neighborhood, Health surface); `/weave-view` opens the browser viewer. In other harnesses, read the JSON documents under `.okf/`
|
|
15
|
-
directly.
|
|
8
|
+
Use `weave_repo`. Without the tool, read `<repo>/.okf/` directly. The index is a generated, rebuildable cache; source code is authoritative.
|
|
16
9
|
|
|
17
10
|
## Workflow
|
|
18
11
|
|
|
19
|
-
1.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
`ls`/`find` calls.
|
|
25
|
-
3. **Descend progressively** (design §9): only open files in modules relevant to the user's question. The index gives you the map; the code
|
|
26
|
-
gives you the terrain.
|
|
27
|
-
4. **Read summaries before full files**: if the repo has been deep-scanned (`.okf/repository/summaries/` exists), read the relevant sidecars
|
|
28
|
-
first — they tell you what a file does and its outward surface in 1–3 sentences, so you can decide whether to open the full file at all.
|
|
29
|
-
5. **Answer with structure**: name modules and packages by their indexed paths so the user can jump straight to them.
|
|
12
|
+
1. Check `action=status`: if missing, offer a scan or scan when exploration was requested; if stale, rescan; if fresh, read
|
|
13
|
+
`action=overview`.
|
|
14
|
+
2. Use the overview's languages, packages, modules, and entry points to select relevant paths instead of listing the whole repository.
|
|
15
|
+
3. Read available `.okf/repository/summaries/` sidecars before opening full files.
|
|
16
|
+
4. Inspect the relevant code and cite indexed paths in your answer.
|
|
30
17
|
|
|
31
|
-
##
|
|
18
|
+
## Commands
|
|
32
19
|
|
|
33
|
-
`/weave-scan
|
|
34
|
-
|
|
35
|
-
|
|
20
|
+
- `/weave-scan` refreshes the index (`weave_repo` action=scan).
|
|
21
|
+
- `/weave-scan deep` generates file summaries using the session model. Offer it when summaries are missing or stale; never run it
|
|
22
|
+
implicitly. Only changed content is summarized again.
|
|
23
|
+
- `/weave-view` opens the browser workspace.
|
|
24
|
+
- `/weave-scan sessions [path]` writes session memories to the vault, not the repository index; see `weave-notepad`.
|
|
36
25
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
## On-disk layout
|
|
26
|
+
## Files and trust
|
|
40
27
|
|
|
41
28
|
```text
|
|
42
29
|
.okf/
|
|
43
30
|
├── okf.json # format version + generator
|
|
44
31
|
└── repository/
|
|
45
32
|
├── identity.json # name, remotes, default branch
|
|
46
|
-
├── git.json # HEAD
|
|
33
|
+
├── git.json # HEAD, branch, changed files
|
|
47
34
|
├── structure.json # languages, packages, modules, entry points
|
|
48
|
-
└── summaries/ #
|
|
35
|
+
└── summaries/ # generated file summaries, when present
|
|
49
36
|
```
|
|
50
37
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
Everything in `.okf` is machine-generated (`source: generated`). If the user corrects an interpretation, that correction belongs in the
|
|
54
|
-
vault (see the `weave-notepad` skill) as human knowledge, not in the derived index.
|
|
38
|
+
Index content is `source: generated`. Store user corrections as human knowledge in the vault, never only in the derived index.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: weave-notepad
|
|
3
|
-
description: "
|
|
3
|
+
description: "Create, update, and retrieve durable notes and past decisions. Use for remember/note requests (notes, ai note, note-taking, note-taker), live dictation, interviews, and repairing or suggesting [[wiki-links]]."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Weave Notepad
|
|
@@ -8,26 +8,41 @@ description: "Take and retrieve durable notes in the pi-weave vault. Use when th
|
|
|
8
8
|
The pi-weave vault is the user's long-term memory: plain Markdown notes with front matter under `~/.okf/notes/`. It is shared with the human
|
|
9
9
|
— anything you write here, they can read and edit, and vice versa.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Use `weave_note`. Without the tool, edit the files directly (`PI_WEAVE_VAULT` overrides the vault root). Front matter:
|
|
12
|
+
`title`, `created`, `updated` (ISO-8601), `tags`, and `source: human | agent | generated`.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
## Capture
|
|
14
15
|
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
|
|
16
|
+
- Create notes only on explicit requests: “remember this”, “start a note”, “add to this note”. Do not capture conversation unprompted.
|
|
17
|
+
- Given new content, call `add` directly and report the slug. Do not list the vault, inspect the repository, or run git first.
|
|
18
|
+
- When extending existing knowledge, make one targeted `search`, then `append` to the matching note instead of duplicating it.
|
|
19
|
+
- Ask one short question if content is missing; exploration cannot reveal what the user meant.
|
|
20
|
+
- Use a specific title and 1–4 lowercase tags; reuse existing tags when known.
|
|
21
|
+
- User-supplied words are `source: human`; pass that explicitly to `add`. Agent-drafted notes are `source: agent` (the default).
|
|
22
|
+
Finalization changes presentation, not authorship. Preserve human meaning; put agent additions in a dated “Agent addendum”.
|
|
23
|
+
- Do not store repository-derived facts, temporary task state, or secrets the user has not confirmed are safe to persist.
|
|
22
24
|
|
|
23
|
-
##
|
|
25
|
+
## Dictation mode (continuous compile)
|
|
26
|
+
|
|
27
|
+
During live dictation or interviews, keep the organized note current after every append; do not wait until the session ends:
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
1. `append` with `raw: true` preserves the user's words verbatim under `## Raw`. Never silently reword dictation.
|
|
30
|
+
2. Immediately `finalize` the body above the tail: front-loaded summary, sections, decisions, questions, tasks, entities, and links
|
|
31
|
+
reflecting everything said so far.
|
|
28
32
|
|
|
29
|
-
|
|
33
|
+
Outside dictation, finalize only on request.
|
|
34
|
+
|
|
35
|
+
### How to capture and append raw input
|
|
30
36
|
|
|
37
|
+
- Keep an append-only raw section at the bottom: `---`, then `## Raw`, then the notice shown below.
|
|
38
|
+
- 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; it maintains this format and creates the tail if missing. Do not hand-format it.
|
|
40
|
+
- `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
|
+
entire previous body as a new raw tail before restructuring; the tool does this automatically.
|
|
42
|
+
|
|
43
|
+
When editing files directly, preserve the same format:
|
|
44
|
+
|
|
45
|
+
````markdown
|
|
31
46
|
---
|
|
32
47
|
|
|
33
48
|
## Raw
|
|
@@ -37,109 +52,42 @@ Every note maintains a verbatim, append-only raw section at the bottom separated
|
|
|
37
52
|
<Initial verbatim input>
|
|
38
53
|
```
|
|
39
54
|
|
|
40
|
-
<!-- appended
|
|
55
|
+
<!-- appended YYYY-MM-DD HH:MM -->
|
|
41
56
|
```
|
|
42
|
-
<Follow-up verbatim
|
|
57
|
+
<Follow-up verbatim input>
|
|
43
58
|
```
|
|
59
|
+
````
|
|
44
60
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
1. **Divider and Heading**: The raw section starts with `---` followed by `## Raw` and the notice comment: `<!-- NEVER edit below this line.
|
|
48
|
-
Verbatim user input preserved here. -->`.
|
|
49
|
-
2. **Code Blocks for Verbatim Input**: Always wrap verbatim user lines inside code blocks (triple backticks).
|
|
50
|
-
3. **Date and Time on Appends**: When appending subsequent snippets, prepend each snippet with: `<!-- appended YYYY-MM-DD HH:MM -->`.
|
|
51
|
-
4. **Finalization (`finalize`)**:
|
|
52
|
-
- `finalize` replaces or structures content only above the `---` and `## Raw` section.
|
|
53
|
-
- The `## Raw` block and all verbatim code blocks are never modified or removed.
|
|
54
|
-
|
|
55
|
-
## Dictation mode (continuous compile)
|
|
56
|
-
|
|
57
|
-
During live dictation / interview note-taking (see the skill description), Pi does **not** wait until the end to organize the note. Every
|
|
58
|
-
interactive append is immediately compiled into the body:
|
|
59
|
-
|
|
60
|
-
1. **Append the raw words verbatim** into the `## Raw` tail (`weave_note` action=append with `raw: true` — the tool adds the dated code block
|
|
61
|
-
and creates the tail if missing).
|
|
62
|
-
2. **Then immediately finalize** (`weave_note` action=finalize): rewrite the body *above* the `## Raw` tail — front-loaded summary,
|
|
63
|
-
sections, decisions, questions, tasks, entities, links — so the compiled document reflects everything said so far.
|
|
64
|
-
3. **Never rewrite or remove the `## Raw` tail.** It stays append-only and verbatim; only the body above it changes.
|
|
65
|
-
|
|
66
|
-
The result is a continuously-updated compiled document that stays current throughout the session — not just a raw tail that gets organized
|
|
67
|
-
once at the end.
|
|
61
|
+
## Retrieve
|
|
68
62
|
|
|
69
|
-
|
|
63
|
+
- Known slug: `get`. Otherwise, one targeted `search` with the user's terms; never list the vault to find a note.
|
|
64
|
+
- One result or a unique exact-title match returns the full note. Use it; do not fetch it again. A body marked `complete` needs no `get`.
|
|
65
|
+
- For multiple plausible matches, fetch at most the three strongest slugs together. If still ambiguous, ask for another identifier instead
|
|
66
|
+
of repeating searches. Fetch additional content only when marked as an excerpt.
|
|
67
|
+
- Search accepts ordinary multi-term queries, with exact-phrase matching followed by ranked lexical fallback. Read the match evidence and
|
|
68
|
+
bounded content before another call.
|
|
69
|
+
- Connected notes are discovery context, not query matches. Use them only when their stated relationship matters; connections are lexical or
|
|
70
|
+
explicit, not semantic.
|
|
71
|
+
- Trust repository code over conflicting notes about implementation; flag potentially stale intent.
|
|
70
72
|
|
|
71
|
-
|
|
72
|
-
down". Never promote conversation into a note on your own initiative — capture is explicit by design.
|
|
73
|
+
## Session memory
|
|
73
74
|
|
|
74
|
-
|
|
75
|
+
`/weave-scan sessions [path]` creates searchable notes under `notes/sessions/` from available session transcripts.
|
|
75
76
|
|
|
76
|
-
-
|
|
77
|
-
-
|
|
78
|
-
-
|
|
77
|
+
- These are `source: generated` recollections; a contradicting human decision record wins.
|
|
78
|
+
- Search their `## Takeaways` for reusable lessons before re-deriving a familiar solution.
|
|
79
|
+
- Rescans update changed transcripts while preserving human edits above the raw tail. Session notes remain re-derivable.
|
|
79
80
|
|
|
80
|
-
|
|
81
|
+
Scans spend model tokens. Never run them unprompted; suggest one when asked to recover history or improve memory across sessions. An
|
|
82
|
+
explicit path accepts a history file or directory.
|
|
81
83
|
|
|
82
|
-
|
|
83
|
-
informs what to write, and on a large vault `list` alone floods the context. When the user gives you the content ("note that says X"),
|
|
84
|
-
`add` it and report the slug.
|
|
85
|
-
1. **Search first when adding to existing knowledge** (`weave_note` action=search, with the note's key terms): if a note on the subject
|
|
86
|
-
exists, `append` to it rather than creating a duplicate. Skip this when the user is clearly starting something new — one targeted search,
|
|
87
|
-
never a vault listing.
|
|
88
|
-
2. Title: short noun phrase ("Auth boundary decision", not "Notes").
|
|
89
|
-
3. **Ask only when the content is genuinely missing.** A vague request ("write a note weave") needs one short question, not exploration —
|
|
90
|
-
searching the vault or the repo will not reveal what the user meant.
|
|
91
|
-
4. **Scribble in, verbatim.** When the user is dictating, append their words to the note as rough, verbatim scribbles — no silent rewording.
|
|
92
|
-
Append with `raw: true` so they land under the `## Raw` tail at the end of the note (the tail is created automatically if missing).
|
|
93
|
-
5. **Compile continuously during dictation.** After *every* interactive append in dictation mode, immediately finalize the body *above* the
|
|
94
|
-
raw tail so the compiled doc stays current (see [Dictation mode](#dictation-mode-continuous-compile)). Outside dictation mode,
|
|
95
|
-
compilation stays on request.
|
|
96
|
-
6. **Finalize on request.** When the user says "finalize this" / "clean this up", restructure the body *above* the raw tail: front-loaded
|
|
97
|
-
summary, sections, entities, links. Use `weave_note` action=finalize (or edit the file directly in other harnesses). Move nothing out of
|
|
98
|
-
`## Raw` — it is append-only and never rewritten. A note with no `## Raw` tail yet gets its entire pre-finalize body preserved as a new
|
|
99
|
-
raw tail: finalization is editorial, never destructive.
|
|
100
|
-
7. Tags: 1–4 lowercase tags; reuse existing tags when possible.
|
|
101
|
-
8. Provenance: notes the user scribbled stay `source: human` (finalization is editorial, not authorship) — pass `source: "human"` to `add`
|
|
102
|
-
for user-scribbled notes. Notes you draft from scratch are `source: agent` (the default). Never overwrite a `source: human` note's
|
|
103
|
-
meaning; append with a dated "Agent addendum" section instead.
|
|
84
|
+
## Links
|
|
104
85
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
- They are `source: generated`, not human knowledge. Treat one as a recollection of what a past session did, not as a decision record; a human note that contradicts it wins.
|
|
110
|
-
- Each carries a `## Takeaways` section: reusable technical lessons (gotchas, root causes, non-obvious rules) from that session. When the user hits a problem that smells familiar, search the vault before re-deriving the answer — a previous session may already have paid for it.
|
|
111
|
-
- They are re-derivable. The scan rewrites a note in place when its transcript changes, preserving human edits above the raw tail, so no session note is the only copy of anything.
|
|
112
|
-
|
|
113
|
-
The scan is opt-in and never runs on its own. Suggest it when the user asks why the agent keeps forgetting across sessions, or wants history from another tool (`/weave-scan sessions <path>` accepts any history file or directory). Never run it unprompted: it spends model tokens per changed session.
|
|
114
|
-
|
|
115
|
-
## Retrieving knowledge
|
|
116
|
-
|
|
117
|
-
Use `weave_note` action=search with the user's key terms, then `get` the best hits. When a note and the repository index disagree, trust the
|
|
118
|
-
repository for facts about code and flag the discrepancy — the note may be stale intent.
|
|
119
|
-
|
|
120
|
-
## Repairing stale links
|
|
121
|
-
|
|
122
|
-
A link written as a bare title or basename — `[[Quarterly Roadmap]]` when the note is `planning/roadmap-2026` — resolves to nothing.
|
|
123
|
-
**Never reconnect a vault by reading every note and guessing which ones relate.** Run the deterministic pass instead:
|
|
124
|
-
|
|
125
|
-
```jsonc
|
|
126
|
-
weave_note { "action": "links" } // report: fixable / ambiguous / unresolvable
|
|
127
|
-
weave_note { "action": "links", "fix": true } // apply only the unambiguous repairs
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
It resolves by exact slug, then unique basename, then unique title — each requiring exactly one candidate. Ambiguous links are reported
|
|
131
|
-
with their candidates and never guessed; unresolvable ones point at notes that were never written. Aliases are preserved, the `## Raw`
|
|
132
|
-
tail and code fences are never touched, and `updated` is not bumped. Report first, apply after the user sees it.
|
|
133
|
-
|
|
134
|
-
To find connections that were **never written** — two notes that belong together but have never referenced each other — use `suggest`:
|
|
135
|
-
|
|
136
|
-
```jsonc
|
|
137
|
-
weave_note { "action": "suggest" } // strongest unlinked pairs
|
|
138
|
-
weave_note { "action": "suggest", "slug": "some/note" } // what relates to one note
|
|
139
|
-
```
|
|
86
|
+
Use `links` to report stale targets, then `links` with `fix: true` after the user reviews the report. Resolution requires exactly one
|
|
87
|
+
candidate: exact slug, then basename, then slugified title. Never guess ambiguous targets or invent content for missing notes. Repairs
|
|
88
|
+
preserve aliases, raw tails, code fences, and `updated`; do not reconstruct links by reading the entire vault and guessing.
|
|
140
89
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
confirm.
|
|
90
|
+
Use `suggest` (optionally with `slug` or `limit`) for unwritten connections. It reports unlinked pairs with shared-term evidence and never
|
|
91
|
+
writes. Propose relevant pairs and add links only after user confirmation; similarity is not an established relationship.
|
|
144
92
|
|
|
145
|
-
See [references/link-repair.md](references/link-repair.md) for
|
|
93
|
+
See [references/link-repair.md](references/link-repair.md) for examples and repair guarantees.
|
|
@@ -1,90 +1,42 @@
|
|
|
1
|
-
# Link repair
|
|
1
|
+
# Link repair
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
`planning/roadmap-2026` — or when it points at a note that was never written. The graph then shows an isolated note that is in fact well
|
|
5
|
-
connected.
|
|
6
|
-
|
|
7
|
-
**Never reconnect a vault by reading it.** Do not search the vault note by note, infer which notes "feel related", and hand-write links.
|
|
8
|
-
That is slow, costs tokens, and is not reproducible — two runs give two different answers. There is a deterministic pass that does it in
|
|
9
|
-
one shot.
|
|
10
|
-
|
|
11
|
-
## The tool
|
|
3
|
+
Use deterministic repair for stale `[[wiki-links]]`; do not read every note and guess connections.
|
|
12
4
|
|
|
13
5
|
```jsonc
|
|
14
|
-
weave_note { "action": "links" } //
|
|
15
|
-
weave_note { "action": "links", "fix": true } // apply
|
|
6
|
+
weave_note { "action": "links" } // report
|
|
7
|
+
weave_note { "action": "links", "fix": true } // apply unambiguous repairs
|
|
16
8
|
```
|
|
17
9
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Always run the report first, read it, then apply. The report is cheap (one pass over the vault, no model calls).
|
|
21
|
-
|
|
22
|
-
## How targets resolve
|
|
23
|
-
|
|
24
|
-
Three rules, tried in order. A rule fires only when it yields **exactly one** candidate:
|
|
25
|
-
|
|
26
|
-
| # | Rule | Example |
|
|
27
|
-
|---|------|---------|
|
|
28
|
-
| 1 | exact slug | `[[planning/roadmap-2026]]` — already correct, left alone |
|
|
29
|
-
| 2 | unique basename | `[[roadmap-2026]]` → `planning/roadmap-2026` |
|
|
30
|
-
| 3 | unique slugified title | `[[Quarterly Roadmap]]` → `planning/roadmap-2026` |
|
|
31
|
-
|
|
32
|
-
Anything else is reported, never guessed:
|
|
33
|
-
|
|
34
|
-
- **ambiguous** — several notes match (two `plan.md` in different folders). The report lists the candidates; a human picks one, or you
|
|
35
|
-
ask. Do not choose on their behalf.
|
|
36
|
-
- **unresolvable** — no note matches. The link points at something never written. Offer to create the note or drop the link; **never
|
|
37
|
-
invent content to satisfy a link.**
|
|
10
|
+
Without the tool, call `repairVaultLinks(vaultRoot, { apply })` from `pi-weave/core`. Report first, then apply after user review; never run
|
|
11
|
+
`fix: true` unprompted on a vault you did not just change.
|
|
38
12
|
|
|
39
|
-
##
|
|
13
|
+
## Resolution
|
|
40
14
|
|
|
41
|
-
|
|
42
|
-
only the target moves.
|
|
43
|
-
- **Does not touch the `## Raw` tail.** A link inside dictation is the user's words, quoted. Off limits, always.
|
|
44
|
-
- **Does not touch fenced code blocks.** `[[…]]` in a code sample is a string literal.
|
|
45
|
-
- **Does not bump `updated`.** A repair is bookkeeping, not an edit; bumping it would reorder the whole vault by recency.
|
|
46
|
-
- **Is idempotent.** A second run finds nothing.
|
|
15
|
+
Try these in order; each requires exactly one candidate:
|
|
47
16
|
|
|
48
|
-
|
|
17
|
+
| Rule | Example |
|
|
18
|
+
|------|---------|
|
|
19
|
+
| Exact slug | `[[planning/roadmap-2026]]` — unchanged |
|
|
20
|
+
| Unique basename | `[[roadmap-2026]]` → `planning/roadmap-2026` |
|
|
21
|
+
| Unique slugified title | `[[Quarterly Roadmap]]` → `planning/roadmap-2026` |
|
|
49
22
|
|
|
50
|
-
|
|
51
|
-
|
|
23
|
+
- **Ambiguous:** report candidates and ask; never choose for the user.
|
|
24
|
+
- **Unresolvable:** offer to create the missing note or remove the link; never invent content to satisfy it.
|
|
52
25
|
|
|
53
|
-
|
|
26
|
+
Repairs preserve visible text through aliases: `[[Quarterly Roadmap]]` becomes `[[planning/roadmap-2026|Quarterly Roadmap]]`. They leave raw
|
|
27
|
+
tails, fenced code, and `updated` untouched. A second run makes no changes. `renameNote`, `moveNote`, and `renameFolder` already repair
|
|
28
|
+
inbound links automatically.
|
|
54
29
|
|
|
55
|
-
|
|
56
|
-
other. That is `suggest`:
|
|
30
|
+
## Unwritten connections
|
|
57
31
|
|
|
58
32
|
```jsonc
|
|
59
|
-
weave_note { "action": "suggest" }
|
|
60
|
-
weave_note { "action": "suggest", "slug": "some/note" }
|
|
33
|
+
weave_note { "action": "suggest" } // strongest unlinked pairs
|
|
34
|
+
weave_note { "action": "suggest", "slug": "some/note" } // one note's candidates
|
|
61
35
|
weave_note { "action": "suggest", "limit": 40 }
|
|
62
36
|
```
|
|
63
37
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
Every suggestion cites the shared terms that earned it. **Read the evidence, not the score** — a list like `shared: acme-1234, release-pipeline`
|
|
69
|
-
is checkable, `0.16` is not.
|
|
70
|
-
|
|
71
|
-
### suggest never writes
|
|
72
|
-
|
|
73
|
-
This is the rule that matters. `suggest` only reports; there is no `fix`. A similarity score is a soft signal and a `[[link]]` is a hard claim —
|
|
74
|
-
once written into a body it is indistinguishable from one the user wrote deliberately. Good scores here are around 0.1–0.3, not 0.9, so treat the
|
|
75
|
-
output as a shortlist for a human:
|
|
76
|
-
|
|
77
|
-
1. Run `suggest`, read the shared terms.
|
|
78
|
-
2. Propose the worthwhile pairs **to the user**.
|
|
79
|
-
3. Add `[[wikilinks]]` only to those they confirm.
|
|
80
|
-
|
|
81
|
-
Never bulk-apply suggestions, and never present one as an established connection.
|
|
82
|
-
|
|
83
|
-
## When to run it
|
|
84
|
-
|
|
85
|
-
- The user asks to "fix the links in" their notes — `links`.
|
|
86
|
-
- The health panel or `/weave` reports dangling links — `links`.
|
|
87
|
-
- After bulk-importing or reorganising notes outside the tool — `links`.
|
|
88
|
-
- The user asks what a note "relates to", or to "connect" / "link up" the vault — `suggest`, then confirm before writing.
|
|
38
|
+
Suggestions rank unlinked pairs by IDF-weighted cosine over title, tags, and body. Rare shared vocabulary matters more than common terms.
|
|
39
|
+
Read the cited terms, not just the score. `suggest` never writes and has no `fix`: propose useful pairs and add links only after
|
|
40
|
+
confirmation. Never bulk-apply suggestions or present them as established connections.
|
|
89
41
|
|
|
90
|
-
|
|
42
|
+
Use `links` for dangling links or after external bulk imports; use `suggest` when asked to discover relationships or connect notes.
|