pi-weave 0.1.7 → 0.1.9

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.
Files changed (98) hide show
  1. package/README.md +123 -37
  2. package/package.json +17 -5
  3. package/skills/weave-notepad/SKILL.md +13 -4
  4. package/src/core/cache/workspace.ts +466 -0
  5. package/src/core/concurrency.ts +36 -0
  6. package/src/core/frontmatter.ts +270 -23
  7. package/src/core/git.ts +19 -0
  8. package/src/core/graph/build.ts +97 -5
  9. package/src/core/graph/current.ts +41 -28
  10. package/src/core/graph/mentions.ts +170 -0
  11. package/src/core/graph/model.ts +39 -0
  12. package/src/core/graph/wikilinks.ts +5 -1
  13. package/src/core/index.ts +14 -0
  14. package/src/core/openInEditor.ts +69 -0
  15. package/src/core/paths.ts +7 -0
  16. package/src/core/sessions.ts +929 -0
  17. package/src/core/summaries.ts +1 -19
  18. package/src/core/types.ts +40 -0
  19. package/src/core/vault.ts +739 -57
  20. package/src/core/view/cluster.ts +262 -0
  21. package/src/core/view/detail.ts +118 -0
  22. package/src/core/view/focus.ts +109 -0
  23. package/src/core/view/health.ts +156 -0
  24. package/src/core/view/index.ts +15 -0
  25. package/src/core/view/links.ts +105 -0
  26. package/src/core/view/time.ts +47 -0
  27. package/src/core/view/tree.ts +269 -0
  28. package/src/core/view/types.ts +39 -0
  29. package/src/core/workspace.ts +3 -3
  30. package/src/pi/index.ts +248 -48
  31. package/src/pi/sessionScan.ts +104 -0
  32. package/src/pi/summarize.ts +24 -4
  33. package/src/pi/tools/noteTool.ts +13 -4
  34. package/src/pi/viewer/tui/branding.ts +8 -7
  35. package/src/pi/viewer/tui/explorer.ts +5 -3
  36. package/src/pi/viewer/tui/model.ts +46 -667
  37. package/src/pi/viewer/tui/openNote.ts +7 -56
  38. package/src/pi/viewer/tui/surface/explore.ts +4 -2
  39. package/src/pi/viewer/web/run.ts +331 -0
  40. package/src/web/client/api.dom.ts +40 -0
  41. package/src/web/client/api.ts +472 -0
  42. package/src/web/client/bootstrap.ts +58 -0
  43. package/src/web/client/context/context.model.ts +313 -0
  44. package/src/web/client/dist/app.js +764 -0
  45. package/src/web/client/graph/Graph.tsx +209 -0
  46. package/src/web/client/graph/column.model.ts +372 -0
  47. package/src/web/client/graph/dynamics.ts +176 -0
  48. package/src/web/client/graph/graph.model.ts +546 -0
  49. package/src/web/client/graph/positions.ts +380 -0
  50. package/src/web/client/graph/project.ts +153 -0
  51. package/src/web/client/graph/renderer.dom.ts +52 -0
  52. package/src/web/client/graph/renderer.ts +339 -0
  53. package/src/web/client/graph/scheme.ts +44 -0
  54. package/src/web/client/live.model.ts +275 -0
  55. package/src/web/client/live.ts +151 -0
  56. package/src/web/client/main.tsx +27 -0
  57. package/src/web/client/note/Editor.tsx +102 -0
  58. package/src/web/client/note/Note.tsx +113 -0
  59. package/src/web/client/note/editor.controller.ts +151 -0
  60. package/src/web/client/note/editor.model.ts +636 -0
  61. package/src/web/client/note/note.model.ts +738 -0
  62. package/src/web/client/search/SearchPalette.tsx +105 -0
  63. package/src/web/client/search/search.model.ts +588 -0
  64. package/src/web/client/search/search.ts +107 -0
  65. package/src/web/client/selection.storage.ts +69 -0
  66. package/src/web/client/shell/Columns.tsx +161 -0
  67. package/src/web/client/shell/ContextRail.tsx +87 -0
  68. package/src/web/client/shell/Divider.tsx +44 -0
  69. package/src/web/client/shell/FocusTrap.tsx +56 -0
  70. package/src/web/client/shell/Header.tsx +64 -0
  71. package/src/web/client/shell/HelpOverlay.tsx +70 -0
  72. package/src/web/client/shell/Shell.tsx +210 -0
  73. package/src/web/client/shell/StatusBar.tsx +28 -0
  74. package/src/web/client/shell/cssvars.ts +70 -0
  75. package/src/web/client/shell/drag.model.ts +170 -0
  76. package/src/web/client/shell/focus.model.ts +100 -0
  77. package/src/web/client/shell/keys.model.ts +453 -0
  78. package/src/web/client/shell/keys.ts +59 -0
  79. package/src/web/client/shell/layout.model.ts +526 -0
  80. package/src/web/client/shell/shell.model.ts +333 -0
  81. package/src/web/client/shell/theme.ts +490 -0
  82. package/src/web/client/shell/viewport.ts +29 -0
  83. package/src/web/client/state.ts +89 -0
  84. package/src/web/client/tree/Tree.tsx +141 -0
  85. package/src/web/client/tree/tree.model.ts +674 -0
  86. package/src/web/client/workspace.ts +278 -0
  87. package/src/web/server/page.ts +258 -0
  88. package/src/web/server/routes.ts +987 -0
  89. package/src/web/server/security.ts +361 -0
  90. package/src/web/server/server.ts +275 -0
  91. package/src/web/server/sse.ts +321 -0
  92. package/src/web/server/watcher.ts +507 -0
  93. package/src/web/shared/graph.ts +213 -0
  94. package/src/web/shared/layout.ts +314 -0
  95. package/src/web/shared/logo.ts +11 -0
  96. package/src/web/shared/metrics.ts +136 -0
  97. package/src/web/shared/view.ts +200 -0
  98. package/src/web/shared/wire.ts +358 -0
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # pi-weave
2
2
 
3
3
  <p align="center">
4
- <img src="https://raw.githubusercontent.com/EranYonai/pi-weave/main/docs/pi-weave-logo.jpg" alt="pi-weave — an agent-native knowledge workspace" width="220"/>
4
+ <img src="https://raw.githubusercontent.com/EranYonai/pi-weave/main/docs/pi-weave-logo.png" alt="pi-weave — an agent-native knowledge workspace" width="220"/>
5
5
  </p>
6
6
 
7
7
  <p align="center">
@@ -15,61 +15,116 @@
15
15
 
16
16
  pi-weave is a [pi](https://github.com/earendil-works/pi) extension with two faces that are secretly one:
17
17
 
18
- 1. **A smart notepad with AI skills.** A persistent vault of knowledge — decisions, ideas, people, meetings — stored as plain Markdown notes
19
- with front matter under `~/.okf/notes/`. Your agent reads and writes it *with* you; everything is editable by hand in any editor.
18
+ 1. **A smart notepad.** A persistent vault of knowledge — decisions, ideas, people, meetings — stored as plain Markdown notes with YAML
19
+ front matter under `~/.okf/notes/`. Your agent reads and writes it *with* you through the `weave_note` tool; everything stays editable by
20
+ hand in any editor.
20
21
 
21
- 2. **A repository exploration engine.** A derived, git-aware knowledge index of the repo you're in, living at `<repo>/.okf/` — structure,
22
- languages, packages, modules, entry points, and staleness state. Rebuildable, disposable, never the source of truth.
22
+ 2. **A repository exploration engine.** A derived, git-aware knowledge index of the repo you are standing in, living at `<repo>/.okf/` —
23
+ structure, languages, packages, modules, entry points, and staleness state. Built and read through the `weave_repo` tool. Rebuildable,
24
+ disposable, never the source of truth.
23
25
 
24
- And one rule across both: **everything is equally usable by humans and agents.** No opaque databases. No lock-in formats.
26
+ One rule spans both: **everything is equally readable by humans and agents.** Markdown and JSON on disk, no opaque database, no lock-in
27
+ format. Every generated artefact carries provenance (`human`, `agent` or `generated`), so agent-written content never masquerades as
28
+ something you wrote.
25
29
 
26
30
  ```
27
- 🧵 vault:12 · my-project:ok ← pi's status line when weave is active
31
+ 🕸️ vault:12 · my-project:ok ← pi's status line when weave is active
28
32
  ```
29
33
 
34
+ See [docs/design.md](docs/design.md) for the reasoning behind all of it.
35
+
30
36
  ## Install
31
37
 
32
38
  ```bash
33
- pi install npm:pi-weave # from npm (recommended)
39
+ pi install npm:pi-weave # from npm (recommended)
34
40
  pi install git:github.com/EranYonai/pi-weave # from git
35
- pi install /path/to/pi-weave # local path
41
+ pi install /path/to/pi-weave # local path
36
42
  ```
37
43
 
38
- Or for development: `pi -e ./src/pi/index.ts`.
44
+ Requires Node **>= 20.13.0**. For development against a checkout: `pi -e ./src/pi/index.ts`.
39
45
 
40
- The package is [published on npm](https://www.npmjs.com/package/pi-weave); releases are cut from `main` and auto-published with provenance
41
- attestation ([Publish workflow](.github/workflows/publish.yml)).
46
+ On session start pi-weave detects the repository you are in, checks whether `.okf` exists and is fresh, and reports it in the status footer
47
+ a filled `●` marks weave as active. An unindexed repository gets a one-line nudge; a stale one gets a warning.
42
48
 
43
- ## What you get
49
+ ## Tools and commands
44
50
 
45
51
  | Surface | Name | Purpose |
46
52
  |---|---|---|
47
- | Tool | `weave_note` | list / get / add / append / finalize / search vault notes |
48
- | Tool | `weave_repo` | status / scan / overview of the `.okf` repo index |
53
+ | Tool | `weave_note` | `list` / `get` / `add` / `append` / `finalize` / `search` over vault notes |
54
+ | Tool | `weave_repo` | `status` / `scan` / `overview` of the `.okf` repository index |
49
55
  | Command | `/weave` | workspace dashboard (vault + repository) |
50
- | Command | `/weave-scan` | build/refresh the repository index (light) |
51
- | Command | `/weave-scan deep` | light index + model-summarized sidecars (opt-in, incremental) |
52
- | Command | `/weave-scan-cancel` | stop an in-flight `/weave-scan deep` run |
53
- | Command | `/weave-view` | explore the local knowledge graph in-terminal (keyboard) |
56
+ | Command | `/weave-view` | open the knowledge workspace in your browser |
57
+ | Command | `/weave-scan` | build or refresh the repository index (light) |
58
+ | Command | `/weave-scan deep` | light index plus model-written per-file summaries (opt-in, incremental, background) |
59
+ | Command | `/weave-scan sessions` | summarize pi session history into the vault as memory notes (incremental, background) |
60
+ | Command | `/weave-scan-cancel` | stop an in-flight `/weave-scan deep` or `sessions` run |
54
61
  | Skill | `weave-notepad` | how the agent should take good notes |
55
62
  | Skill | `weave-explore` | how the agent should explore repositories |
56
63
 
57
- **`/weave-view`** explores the knowledge graph in the terminal: an expandable containment tree (Explore), a 1-hop neighborhood
58
- (Focus), a selected-node detail view with note/`.okf` bodies, and a staleness + link health surface all keyboard-driven and read-only.
59
- It reads disk live (never a stale cache) over the `GraphModel` assembled from the vault + repository index; a pure, harness-free view-model
60
- (`src/pi/viewer/tui/model.ts`) backs the `WeaveExplorer` component. See `docs/weave-view-tui-design.md`.
64
+ `/weave-scan deep` refreshes the light index and then writes a short model summary per file to `.okf/repository/summaries/`, skipping files
65
+ whose content hash has not changed since their last summary. It costs tokens, so it never runs implicitly and it runs in the background,
66
+ so `/weave-scan-cancel` can stop it mid-flight.
67
+
68
+ `/weave-scan sessions` is the repo-agnostic sibling (docs/session-scan.md): it reads every pi session transcript under
69
+ `~/.pi/agent/sessions/`, hashes each file while reading it, and writes one generated vault note per changed session under
70
+ `~/.okf/notes/sessions/` — pi's memory as first-class, wikilinked notes in an inner folder of the vault graph. Unchanged transcripts cost no
71
+ LLM calls at all, and older layouts migrate automatically on the next scan.
72
+
73
+ ## The workspace
74
+
75
+ `/weave-view` opens a browser knowledge workspace over the same graph the tools see — the vault and the repository index as one model.
76
+
77
+ ```bash
78
+ /weave-view # browser workspace (default), opens a tab
79
+ /weave-view --no-open # same server, just prints the URL
80
+ /weave-view tui # the in-terminal explorer instead
81
+ ```
82
+
83
+ Three resizable columns and a context rail:
84
+
85
+ - **Tree** — an expandable containment tree over notes and repository structure, with a filter box and provenance cycling.
86
+ - **Note** — the selected note rendered with [marked](https://marked.js.org) and sanitised with DOMPurify. `[[wikilinks]]` navigate inside
87
+ the workspace; links with no target render as ghosts rather than dead text.
88
+ - **Graph** — [sigma.js](https://www.sigmajs.org) v3 on WebGL with a [d3-force](https://d3js.org/d3-force) layout: neighbourhood highlight
89
+ on selection, semantic zoom that reveals labels as you go in, and cluster collapse as real graph reduction rather than hiding.
90
+ - **Context rail** — links, backlinks, tags and mentions for whatever is selected, every entry clickable.
91
+
92
+ Selecting anywhere highlights everywhere: the tree, the note body, the graph and the rail are lenses onto one selection. Updates arrive live
93
+ over SSE as files change on disk, so an agent writing a note shows up without a refresh.
94
+
95
+ `⌘K` opens a search palette spanning both faces (notes ranked with snippets, repository nodes by label). The whole workspace is keyboard
96
+ drivable — `⌘1/2/3` focus a column, `/` filters the tree, `g` fits the graph, `Esc` clears, and `?` lists the rest. Column widths persist.
97
+
98
+ The workspace is **read-first**, but no longer read-only. `⌘E` toggles the note column between read and edit, `⌘S` saves, and every save
99
+ carries the revision read at load — a stale one gets a `409` and a choice of reload, overwrite or keep editing. The draft is never silently
100
+ discarded or clobbered: a remote change arriving over SSE for the note you are editing is recorded rather than applied, and comes back as
101
+ that same `409` when you save.
61
102
 
62
- > The earlier in-browser graph viewer (`/weave-view` in a browser) has been retired and is being rebuilt on pixi.js; until then
63
- > `/weave-view` opens the in-terminal explorer.
103
+ Front matter the engine does not own survives a browser save **byte-identically** `aliases`, `cssclass` and a `tags:` block list all come
104
+ back unchanged and in place, with `updated:` the only line a save moves. That is the P5 exit criterion, and
105
+ `tests/web/editor.roundtrip.test.ts` drives it through the real client, over a real socket, into a real vault — it is what makes editing
106
+ here safe alongside Obsidian.
64
107
 
65
- On session start, pi-weave detects the repository you're in, checks whether `.okf` exists and is fresh, and says so in the status footer — a
66
- filled `●` marks weave as active (a deep scan spins it while running).
108
+ Rename and delete have routes, client functions and tests but **no UI**, deliberately: the vault has no trash, so the confirmation flow
109
+ around a destructive button is a design decision rather than a wiring task. Notes are still authorable through the `weave_note` tool or by
110
+ hand, and the note toolbar's "Open in $EDITOR" hands the file to yours. `/weave-view tui` is the read-only in-terminal explorer — the same
111
+ model, a containment tree, a 1-hop focus view, node detail and a link-health surface, for when you are on the far end of an SSH session.
67
112
 
68
- **`/weave-scan deep`** is the opt-in, incremental deep pass: it refreshes the light index and then writes a short model summary per file to
69
- `.okf/repository/summaries/`, skipping files whose content hash is unchanged since their last summary. It costs tokens, so it never runs
70
- implicitly — and it runs in the background, so `/weave-scan-cancel` can stop it mid-flight.
113
+ ### The local server
71
114
 
72
- ## The formats (why everything is portable)
115
+ The workspace server is deliberately small and deliberately paranoid, because loopback is not an authorisation boundary — any local process
116
+ can reach the port, and any website you visit can try to via DNS rebinding. Four layers:
117
+
118
+ 1. Binds `127.0.0.1` on an ephemeral port. Never `0.0.0.0`.
119
+ 2. A `Host` header allowlist (`127.0.0.1:PORT`, `localhost:PORT`, `[::1]:PORT`), which is what actually stops rebinding.
120
+ 3. A 256-bit per-session token, handed off once in the URL and exchanged for an `HttpOnly; SameSite=Strict` cookie via a redirect that drops
121
+ it from the address bar. Compared in constant time.
122
+ 4. `Origin` validated when present, and required on anything that is not a `GET` or `HEAD`.
123
+
124
+ The page is served under a nonce-only CSP — `default-src 'none'`, no `unsafe-inline`, no `unsafe-eval`, no CORS headers at all. The server
125
+ shuts itself down after 30 minutes with no client attached, and always at the end of the pi session.
126
+
127
+ ## The formats
73
128
 
74
129
  Vault note (`~/.okf/notes/auth-boundary.md`):
75
130
 
@@ -96,19 +151,50 @@ Repository index (`<repo>/.okf/`):
96
151
  └── structure.json # languages, packages, modules, entry points
97
152
  ```
98
153
 
99
- The `.okf` index is **derived**: delete it, rescan, lose nothing. By default it's excluded from git locally (`.git/info/exclude`);
100
- committing it for team sharing is a deliberate opt-in.
154
+ The `.okf` index is **derived**: delete it, rescan, lose nothing. By default it is excluded from git locally (`.git/info/exclude`);
155
+ committing it to share with a team is a deliberate opt-in. The vault location can be overridden with `PI_WEAVE_VAULT`.
156
+
157
+ ## Zero runtime dependencies
158
+
159
+ `package.json` declares no `dependencies`. The four peers (`@earendil-works/pi-ai`, `@earendil-works/pi-coding-agent`,
160
+ `@earendil-works/pi-tui`, `typebox`) are supplied by the pi harness, which loads `src/pi/index.ts` as TypeScript directly — installing
161
+ pi-weave runs no build step.
162
+
163
+ The browser client cannot work that way, so preact, sigma, graphology, d3-force, marked and DOMPurify are **devDependencies** bundled into a
164
+ committed artifact at `src/web/client/dist/app.js`. They are inputs to a build, not runtime requirements of the package.
101
165
 
102
166
  ## For other agent harnesses
103
167
 
104
- The on-disk artifacts and `src/core` are harness-agnostic by design — Claude Code and opencode adapters are on the roadmap (docs/design.md
105
- §21), and the skills follow the [Agent Skills standard](https://agentskills.io/specification).
168
+ The skills follow the [Agent Skills standard](https://agentskills.io/specification), and the on-disk artefacts and `src/core` are
169
+ harness-agnostic by design: `src/core` may not import anything pi-specific. Claude Code and opencode adapters are on the roadmap
170
+ ([docs/design.md](docs/design.md) §21).
171
+
172
+ ## Documentation
173
+
174
+ | Where | What |
175
+ |---|---|
176
+ | [docs/design.md](docs/design.md) | the design document — *why* pi-weave is shaped this way |
177
+ | [docs/weave-workspace.md](docs/weave-workspace.md) | the browser workspace: library choices with measurements, security model, phases |
178
+ | [docs/weave-view-tui-design.md](docs/weave-view-tui-design.md) | the in-terminal explorer |
179
+ | [AGENTS.md](AGENTS.md) | contributor and agent rules — read before changing anything |
106
180
 
107
181
  ## Development
108
182
 
109
183
  ```bash
110
184
  npm install
111
- npm run check # typecheck + tests with coverage gate (≥95%)
185
+ npm run typecheck # tsc --noEmit, strict, both projects
186
+ npm test # vitest run
187
+ npm run coverage # the 95% gate (lines, branches, functions, statements)
188
+ npm run build:web # rebuild the committed browser bundle
189
+ npm run check # typecheck + bundle drift check + coverage — run this before committing
112
190
  ```
113
191
 
114
- See [AGENTS.md](AGENTS.md) for contributor/agent rules and [docs/design.md](docs/design.md) for the full design.
192
+ Two rules worth knowing before you send a patch. Coverage must stay at or above **95%** on every metric; the gate is enforced by vitest
193
+ thresholds and `npm run check` fails below it. And the committed web bundle must match its source — `npm run check` rebuilds it in memory
194
+ and byte-compares, so run `npm run build:web` and commit the result whenever you touch `src/web/`.
195
+
196
+ Never commit to `main`; branch, then open a PR. See [AGENTS.md](AGENTS.md) for the rest.
197
+
198
+ ## Licence
199
+
200
+ [MIT](LICENSE).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-weave",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "An agent-native knowledge workspace for your life and your code. Smart notepad + repository exploration, readable by humans and agents alike.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -23,7 +23,7 @@
23
23
  "homepage": "https://github.com/EranYonai/pi-weave#readme",
24
24
  "bugs": "https://github.com/EranYonai/pi-weave/issues",
25
25
  "engines": {
26
- "node": ">=20"
26
+ "node": ">=20.13.0"
27
27
  },
28
28
  "exports": {
29
29
  "./core": "./src/core/index.ts"
@@ -41,13 +41,15 @@
41
41
  "skills": [
42
42
  "./skills"
43
43
  ],
44
- "image": "https://raw.githubusercontent.com/EranYonai/pi-weave/main/docs/pi-weave-logo.jpg"
44
+ "image": "https://raw.githubusercontent.com/EranYonai/pi-weave/main/docs/pi-weave-logo.png"
45
45
  },
46
46
  "scripts": {
47
47
  "test": "vitest run",
48
48
  "coverage": "vitest run --coverage",
49
- "typecheck": "tsc --noEmit",
50
- "check": "npm run typecheck && npm run coverage",
49
+ "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.web.json",
50
+ "build:web": "node scripts/build-web.mjs",
51
+ "build:web:check": "node scripts/build-web.mjs --check",
52
+ "check": "npm run typecheck && npm run build:web:check && npm run coverage",
51
53
  "rewrap:md": "node scripts/rewrap-md.mjs",
52
54
  "rewrap:md:check": "node scripts/rewrap-md.mjs --check",
53
55
  "prepublishOnly": "npm run check"
@@ -62,8 +64,18 @@
62
64
  "@earendil-works/pi-ai": "^0.84.2",
63
65
  "@earendil-works/pi-coding-agent": "^0.84.2",
64
66
  "@earendil-works/pi-tui": "^0.84.2",
67
+ "@preact/signals": "^2.11.1",
68
+ "@types/d3-force": "^3.0.10",
65
69
  "@types/node": "^24.0.0",
66
70
  "@vitest/coverage-v8": "^3.2.4",
71
+ "d3-force": "^3.0.0",
72
+ "dompurify": "^3.4.14",
73
+ "esbuild": "^0.28.2",
74
+ "graphology": "^0.26.0",
75
+ "graphology-types": "^0.24.8",
76
+ "marked": "^18.0.10",
77
+ "preact": "^10.29.8",
78
+ "sigma": "^3.0.3",
67
79
  "typebox": "1.3.7",
68
80
  "typescript": "^5.8.0",
69
81
  "vitest": "^3.2.4"
@@ -15,10 +15,17 @@ In pi, use the `weave_note` tool. In other harnesses (or when the tool is not av
15
15
  - **Notes** live at `~/.okf/notes/<slug>.md` (vault root overridable via `PI_WEAVE_VAULT`).
16
16
  - Each note has YAML front matter: `title`, `created`, `updated` (ISO-8601), `tags: [..]`, and `source: human | agent | generated`.
17
17
  - `weave_note` actions: `list`, `get`, `add`, `append`, `finalize`, `search`. `finalize` restructures the body *above* the `## Raw` tail and
18
- preserves the tail verbatim.
18
+ preserves the tail verbatim — a body with no tail yet is preserved **in full** as a newly created tail, so finalization never destroys
19
+ dictation.
20
+ - **Dictation appends**: use `append` with `raw: true` — the tool appends the text verbatim into the `## Raw` tail as a dated fenced block,
21
+ creating the tail if the note has none. In pi, never hand-format the raw tail; the tool maintains it.
19
22
 
20
23
  ## Raw Tail Format
21
24
 
25
+ In pi you rarely format this by hand: `weave_note` append with `raw: true` appends a dated fenced block into the tail (and creates the whole
26
+ tail — separator, heading, notice — when the note has none). The format below is what that produces, and what to write when editing files
27
+ directly or working in other harnesses.
28
+
22
29
  Every note maintains a verbatim, append-only raw section at the bottom separated by a horizontal rule (`---`):
23
30
 
24
31
  ---
@@ -50,7 +57,8 @@ Every note maintains a verbatim, append-only raw section at the bottom separated
50
57
  During live dictation / interview note-taking (see the skill description), Pi does **not** wait until the end to organize the note. Every
51
58
  interactive append is immediately compiled into the body:
52
59
 
53
- 1. **Append the raw words verbatim** to the `## Raw` tail as usual (a dated `<!-- appended YYYY-MM-DD HH:MM -->` code block).
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).
54
62
  2. **Then immediately finalize** (`weave_note` action=finalize): rewrite the body *above* the `## Raw` tail — front-loaded summary,
55
63
  sections, decisions, questions, tasks, entities, links — so the compiled document reflects everything said so far.
56
64
  3. **Never rewrite or remove the `## Raw` tail.** It stays append-only and verbatim; only the body above it changes.
@@ -74,13 +82,14 @@ down". Never promote conversation into a note on your own initiative — capture
74
82
  1. **Search first** (`weave_note` action=search): if a note exists, `append` to it rather than creating a duplicate.
75
83
  2. Title: short noun phrase ("Auth boundary decision", not "Notes").
76
84
  3. **Scribble in, verbatim.** When the user is dictating, append their words to the note as rough, verbatim scribbles — no silent rewording.
77
- Keep them under the `## Raw` tail format at the end of the note.
85
+ Append with `raw: true` so they land under the `## Raw` tail at the end of the note (the tail is created automatically if missing).
78
86
  4. **Compile continuously during dictation.** After *every* interactive append in dictation mode, immediately finalize the body *above* the
79
87
  raw tail so the compiled doc stays current (see [Dictation mode](#dictation-mode-continuous-compile)). Outside dictation mode,
80
88
  compilation stays on request.
81
89
  5. **Finalize on request.** When the user says "finalize this" / "clean this up", restructure the body *above* the raw tail: front-loaded
82
90
  summary, sections, entities, links. Use `weave_note` action=finalize (or edit the file directly in other harnesses). Move nothing out of
83
- `## Raw` — it is append-only and never rewritten.
91
+ `## 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
92
+ raw tail: finalization is editorial, never destructive.
84
93
  6. Tags: 1–4 lowercase tags; reuse existing tags when possible.
85
94
  7. Provenance: notes the user scribbled stay `source: human` (finalization is editorial, not authorship) — pass `source: "human"` to `add`
86
95
  for user-scribbled notes. Notes you draft from scratch are `source: agent` (the default). Never overwrite a `source: human` note's