pi-weave 0.1.7 → 0.1.8

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 (84) hide show
  1. package/README.md +114 -34
  2. package/package.json +16 -4
  3. package/src/core/cache/workspace.ts +466 -0
  4. package/src/core/frontmatter.ts +217 -23
  5. package/src/core/git.ts +19 -0
  6. package/src/core/graph/build.ts +37 -4
  7. package/src/core/graph/current.ts +41 -28
  8. package/src/core/graph/mentions.ts +170 -0
  9. package/src/core/graph/model.ts +24 -0
  10. package/src/core/index.ts +12 -0
  11. package/src/core/openInEditor.ts +69 -0
  12. package/src/core/types.ts +40 -0
  13. package/src/core/vault.ts +477 -43
  14. package/src/core/view/cluster.ts +262 -0
  15. package/src/core/view/detail.ts +118 -0
  16. package/src/core/view/focus.ts +109 -0
  17. package/src/core/view/health.ts +156 -0
  18. package/src/core/view/index.ts +15 -0
  19. package/src/core/view/links.ts +105 -0
  20. package/src/core/view/time.ts +47 -0
  21. package/src/core/view/tree.ts +269 -0
  22. package/src/core/view/types.ts +39 -0
  23. package/src/pi/index.ts +104 -11
  24. package/src/pi/viewer/tui/explorer.ts +4 -2
  25. package/src/pi/viewer/tui/model.ts +46 -667
  26. package/src/pi/viewer/tui/openNote.ts +7 -56
  27. package/src/pi/viewer/tui/surface/explore.ts +4 -2
  28. package/src/pi/viewer/web/run.ts +331 -0
  29. package/src/web/client/api.dom.ts +40 -0
  30. package/src/web/client/api.ts +472 -0
  31. package/src/web/client/bootstrap.ts +58 -0
  32. package/src/web/client/context/context.model.ts +313 -0
  33. package/src/web/client/dist/app.js +751 -0
  34. package/src/web/client/graph/Graph.tsx +158 -0
  35. package/src/web/client/graph/column.model.ts +431 -0
  36. package/src/web/client/graph/graph.model.ts +538 -0
  37. package/src/web/client/graph/positions.ts +339 -0
  38. package/src/web/client/graph/project.ts +153 -0
  39. package/src/web/client/graph/renderer.dom.ts +52 -0
  40. package/src/web/client/graph/renderer.ts +279 -0
  41. package/src/web/client/graph/scheme.ts +44 -0
  42. package/src/web/client/live.model.ts +275 -0
  43. package/src/web/client/live.ts +151 -0
  44. package/src/web/client/main.tsx +27 -0
  45. package/src/web/client/note/Editor.tsx +102 -0
  46. package/src/web/client/note/Note.tsx +113 -0
  47. package/src/web/client/note/editor.controller.ts +151 -0
  48. package/src/web/client/note/editor.model.ts +636 -0
  49. package/src/web/client/note/note.model.ts +738 -0
  50. package/src/web/client/search/SearchPalette.tsx +105 -0
  51. package/src/web/client/search/search.model.ts +588 -0
  52. package/src/web/client/search/search.ts +107 -0
  53. package/src/web/client/shell/Columns.tsx +161 -0
  54. package/src/web/client/shell/ContextRail.tsx +87 -0
  55. package/src/web/client/shell/Divider.tsx +44 -0
  56. package/src/web/client/shell/FocusTrap.tsx +56 -0
  57. package/src/web/client/shell/Header.tsx +54 -0
  58. package/src/web/client/shell/HelpOverlay.tsx +70 -0
  59. package/src/web/client/shell/Shell.tsx +193 -0
  60. package/src/web/client/shell/StatusBar.tsx +28 -0
  61. package/src/web/client/shell/cssvars.ts +70 -0
  62. package/src/web/client/shell/drag.model.ts +170 -0
  63. package/src/web/client/shell/focus.model.ts +100 -0
  64. package/src/web/client/shell/keys.model.ts +453 -0
  65. package/src/web/client/shell/keys.ts +59 -0
  66. package/src/web/client/shell/layout.model.ts +526 -0
  67. package/src/web/client/shell/shell.model.ts +333 -0
  68. package/src/web/client/shell/theme.ts +477 -0
  69. package/src/web/client/shell/viewport.ts +29 -0
  70. package/src/web/client/state.ts +78 -0
  71. package/src/web/client/tree/Tree.tsx +138 -0
  72. package/src/web/client/tree/tree.model.ts +674 -0
  73. package/src/web/client/workspace.ts +214 -0
  74. package/src/web/server/page.ts +256 -0
  75. package/src/web/server/routes.ts +975 -0
  76. package/src/web/server/security.ts +361 -0
  77. package/src/web/server/server.ts +275 -0
  78. package/src/web/server/sse.ts +321 -0
  79. package/src/web/server/watcher.ts +507 -0
  80. package/src/web/shared/graph.ts +206 -0
  81. package/src/web/shared/layout.ts +497 -0
  82. package/src/web/shared/metrics.ts +136 -0
  83. package/src/web/shared/view.ts +200 -0
  84. package/src/web/shared/wire.ts +358 -0
package/README.md CHANGED
@@ -15,61 +15,110 @@
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
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) |
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) |
52
59
  | Command | `/weave-scan-cancel` | stop an in-flight `/weave-scan deep` run |
53
- | Command | `/weave-view` | explore the local knowledge graph in-terminal (keyboard) |
54
60
  | Skill | `weave-notepad` | how the agent should take good notes |
55
61
  | Skill | `weave-explore` | how the agent should explore repositories |
56
62
 
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`.
63
+ `/weave-scan deep` refreshes the light index and then writes a short model summary per file to `.okf/repository/summaries/`, skipping files
64
+ whose content hash has not changed since their last summary. It costs tokens, so it never runs implicitly and it runs in the background,
65
+ so `/weave-scan-cancel` can stop it mid-flight.
66
+
67
+ ## The workspace
68
+
69
+ `/weave-view` opens a browser knowledge workspace over the same graph the tools see — the vault and the repository index as one model.
70
+
71
+ ```bash
72
+ /weave-view # browser workspace (default), opens a tab
73
+ /weave-view --no-open # same server, just prints the URL
74
+ /weave-view tui # the in-terminal explorer instead
75
+ ```
76
+
77
+ Three resizable columns and a context rail:
78
+
79
+ - **Tree** — an expandable containment tree over notes and repository structure, with a filter box and provenance cycling.
80
+ - **Note** — the selected note rendered with [marked](https://marked.js.org) and sanitised with DOMPurify. `[[wikilinks]]` navigate inside
81
+ the workspace; links with no target render as ghosts rather than dead text.
82
+ - **Graph** — [sigma.js](https://www.sigmajs.org) v3 on WebGL with a [d3-force](https://d3js.org/d3-force) layout: neighbourhood highlight
83
+ on selection, semantic zoom that reveals labels as you go in, and cluster collapse as real graph reduction rather than hiding.
84
+ - **Context rail** — links, backlinks, tags and mentions for whatever is selected, every entry clickable.
85
+
86
+ Selecting anywhere highlights everywhere: the tree, the note body, the graph and the rail are lenses onto one selection. Updates arrive live
87
+ over SSE as files change on disk, so an agent writing a note shows up without a refresh.
88
+
89
+ `⌘K` opens a search palette spanning both faces (notes ranked with snippets, repository nodes by label). The whole workspace is keyboard
90
+ drivable — `⌘1/2/3` focus a column, `/` filters the tree, `g` fits the graph, `Esc` clears, and `?` lists the rest. Column widths persist.
91
+
92
+ The workspace is **read-first**, but no longer read-only. `⌘E` toggles the note column between read and edit, `⌘S` saves, and every save
93
+ 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
94
+ discarded or clobbered: a remote change arriving over SSE for the note you are editing is recorded rather than applied, and comes back as
95
+ that same `409` when you save.
61
96
 
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.
97
+ Front matter the engine does not own survives a browser save **byte-identically** `aliases`, `cssclass` and a `tags:` block list all come
98
+ back unchanged and in place, with `updated:` the only line a save moves. That is the P5 exit criterion, and
99
+ `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
100
+ here safe alongside Obsidian.
64
101
 
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).
102
+ Rename and delete have routes, client functions and tests but **no UI**, deliberately: the vault has no trash, so the confirmation flow
103
+ around a destructive button is a design decision rather than a wiring task. Notes are still authorable through the `weave_note` tool or by
104
+ 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
105
+ 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
106
 
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.
107
+ ### The local server
71
108
 
72
- ## The formats (why everything is portable)
109
+ The workspace server is deliberately small and deliberately paranoid, because loopback is not an authorisation boundary — any local process
110
+ can reach the port, and any website you visit can try to via DNS rebinding. Four layers:
111
+
112
+ 1. Binds `127.0.0.1` on an ephemeral port. Never `0.0.0.0`.
113
+ 2. A `Host` header allowlist (`127.0.0.1:PORT`, `localhost:PORT`, `[::1]:PORT`), which is what actually stops rebinding.
114
+ 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
115
+ it from the address bar. Compared in constant time.
116
+ 4. `Origin` validated when present, and required on anything that is not a `GET` or `HEAD`.
117
+
118
+ 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
119
+ shuts itself down after 30 minutes with no client attached, and always at the end of the pi session.
120
+
121
+ ## The formats
73
122
 
74
123
  Vault note (`~/.okf/notes/auth-boundary.md`):
75
124
 
@@ -96,19 +145,50 @@ Repository index (`<repo>/.okf/`):
96
145
  └── structure.json # languages, packages, modules, entry points
97
146
  ```
98
147
 
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.
148
+ The `.okf` index is **derived**: delete it, rescan, lose nothing. By default it is excluded from git locally (`.git/info/exclude`);
149
+ committing it to share with a team is a deliberate opt-in. The vault location can be overridden with `PI_WEAVE_VAULT`.
150
+
151
+ ## Zero runtime dependencies
152
+
153
+ `package.json` declares no `dependencies`. The four peers (`@earendil-works/pi-ai`, `@earendil-works/pi-coding-agent`,
154
+ `@earendil-works/pi-tui`, `typebox`) are supplied by the pi harness, which loads `src/pi/index.ts` as TypeScript directly — installing
155
+ pi-weave runs no build step.
156
+
157
+ The browser client cannot work that way, so preact, sigma, graphology, d3-force, marked and DOMPurify are **devDependencies** bundled into a
158
+ committed artifact at `src/web/client/dist/app.js`. They are inputs to a build, not runtime requirements of the package.
101
159
 
102
160
  ## For other agent harnesses
103
161
 
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).
162
+ The skills follow the [Agent Skills standard](https://agentskills.io/specification), and the on-disk artefacts and `src/core` are
163
+ harness-agnostic by design: `src/core` may not import anything pi-specific. Claude Code and opencode adapters are on the roadmap
164
+ ([docs/design.md](docs/design.md) §21).
165
+
166
+ ## Documentation
167
+
168
+ | Where | What |
169
+ |---|---|
170
+ | [docs/design.md](docs/design.md) | the design document — *why* pi-weave is shaped this way |
171
+ | [docs/weave-workspace.md](docs/weave-workspace.md) | the browser workspace: library choices with measurements, security model, phases |
172
+ | [docs/weave-view-tui-design.md](docs/weave-view-tui-design.md) | the in-terminal explorer |
173
+ | [AGENTS.md](AGENTS.md) | contributor and agent rules — read before changing anything |
106
174
 
107
175
  ## Development
108
176
 
109
177
  ```bash
110
178
  npm install
111
- npm run check # typecheck + tests with coverage gate (≥95%)
179
+ npm run typecheck # tsc --noEmit, strict, both projects
180
+ npm test # vitest run
181
+ npm run coverage # the 95% gate (lines, branches, functions, statements)
182
+ npm run build:web # rebuild the committed browser bundle
183
+ npm run check # typecheck + bundle drift check + coverage — run this before committing
112
184
  ```
113
185
 
114
- See [AGENTS.md](AGENTS.md) for contributor/agent rules and [docs/design.md](docs/design.md) for the full design.
186
+ 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
187
+ thresholds and `npm run check` fails below it. And the committed web bundle must match its source — `npm run check` rebuilds it in memory
188
+ and byte-compares, so run `npm run build:web` and commit the result whenever you touch `src/web/`.
189
+
190
+ Never commit to `main`; branch, then open a PR. See [AGENTS.md](AGENTS.md) for the rest.
191
+
192
+ ## Licence
193
+
194
+ [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.8",
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"
@@ -46,8 +46,10 @@
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"