pi-weave 0.1.6 → 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 (96) hide show
  1. package/README.md +114 -37
  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 +102 -19
  24. package/src/pi/viewer/tui/bodyStore.ts +98 -0
  25. package/src/pi/viewer/tui/branding.ts +154 -0
  26. package/src/pi/viewer/tui/explorer.ts +20 -31
  27. package/src/pi/viewer/tui/model.ts +46 -667
  28. package/src/pi/viewer/tui/openNote.ts +11 -0
  29. package/src/pi/viewer/tui/run.ts +13 -4
  30. package/src/pi/viewer/tui/surface/base.ts +182 -0
  31. package/src/pi/viewer/tui/surface/detail.ts +315 -0
  32. package/src/pi/viewer/tui/surface/explore.ts +206 -0
  33. package/src/pi/viewer/tui/surface/focus.ts +139 -0
  34. package/src/pi/viewer/tui/surface/health.ts +102 -0
  35. package/src/pi/viewer/tui/workspace.ts +381 -0
  36. package/src/pi/viewer/tui/workspaceRoot.ts +530 -0
  37. package/src/pi/viewer/web/run.ts +331 -0
  38. package/src/web/client/api.dom.ts +40 -0
  39. package/src/web/client/api.ts +472 -0
  40. package/src/web/client/bootstrap.ts +58 -0
  41. package/src/web/client/context/context.model.ts +313 -0
  42. package/src/web/client/dist/app.js +751 -0
  43. package/src/web/client/graph/Graph.tsx +158 -0
  44. package/src/web/client/graph/column.model.ts +431 -0
  45. package/src/web/client/graph/graph.model.ts +538 -0
  46. package/src/web/client/graph/positions.ts +339 -0
  47. package/src/web/client/graph/project.ts +153 -0
  48. package/src/web/client/graph/renderer.dom.ts +52 -0
  49. package/src/web/client/graph/renderer.ts +279 -0
  50. package/src/web/client/graph/scheme.ts +44 -0
  51. package/src/web/client/live.model.ts +275 -0
  52. package/src/web/client/live.ts +151 -0
  53. package/src/web/client/main.tsx +27 -0
  54. package/src/web/client/note/Editor.tsx +102 -0
  55. package/src/web/client/note/Note.tsx +113 -0
  56. package/src/web/client/note/editor.controller.ts +151 -0
  57. package/src/web/client/note/editor.model.ts +636 -0
  58. package/src/web/client/note/note.model.ts +738 -0
  59. package/src/web/client/search/SearchPalette.tsx +105 -0
  60. package/src/web/client/search/search.model.ts +588 -0
  61. package/src/web/client/search/search.ts +107 -0
  62. package/src/web/client/shell/Columns.tsx +161 -0
  63. package/src/web/client/shell/ContextRail.tsx +87 -0
  64. package/src/web/client/shell/Divider.tsx +44 -0
  65. package/src/web/client/shell/FocusTrap.tsx +56 -0
  66. package/src/web/client/shell/Header.tsx +54 -0
  67. package/src/web/client/shell/HelpOverlay.tsx +70 -0
  68. package/src/web/client/shell/Shell.tsx +193 -0
  69. package/src/web/client/shell/StatusBar.tsx +28 -0
  70. package/src/web/client/shell/cssvars.ts +70 -0
  71. package/src/web/client/shell/drag.model.ts +170 -0
  72. package/src/web/client/shell/focus.model.ts +100 -0
  73. package/src/web/client/shell/keys.model.ts +453 -0
  74. package/src/web/client/shell/keys.ts +59 -0
  75. package/src/web/client/shell/layout.model.ts +526 -0
  76. package/src/web/client/shell/shell.model.ts +333 -0
  77. package/src/web/client/shell/theme.ts +477 -0
  78. package/src/web/client/shell/viewport.ts +29 -0
  79. package/src/web/client/state.ts +78 -0
  80. package/src/web/client/tree/Tree.tsx +138 -0
  81. package/src/web/client/tree/tree.model.ts +674 -0
  82. package/src/web/client/workspace.ts +214 -0
  83. package/src/web/server/page.ts +256 -0
  84. package/src/web/server/routes.ts +975 -0
  85. package/src/web/server/security.ts +361 -0
  86. package/src/web/server/server.ts +275 -0
  87. package/src/web/server/sse.ts +321 -0
  88. package/src/web/server/watcher.ts +507 -0
  89. package/src/web/shared/graph.ts +206 -0
  90. package/src/web/shared/layout.ts +497 -0
  91. package/src/web/shared/metrics.ts +136 -0
  92. package/src/web/shared/view.ts +200 -0
  93. package/src/web/shared/wire.ts +358 -0
  94. package/src/pi/viewer/browser.ts +0 -29
  95. package/src/pi/viewer/page.ts +0 -1316
  96. package/src/pi/viewer/server.ts +0 -229
package/README.md CHANGED
@@ -15,64 +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` | open the local graph viewer in your browser |
54
- | Command | `/weave-view tui` | explore the same graph in-terminal (keyboard) |
55
60
  | Skill | `weave-notepad` | how the agent should take good notes |
56
61
  | Skill | `weave-explore` | how the agent should explore repositories |
57
62
 
58
- **`/weave-view`** starts a loopback-only server (`127.0.0.1`, random port) and opens an interactive graph of your knowledge space: vault
59
- notes with trust provenance (solid = human, dashed = agent, dimmed = generated), wiki-link edges between notes, and the repository's
60
- structure anchored to git state. It reads disk live on every refresh — never a stale cache. Zoom/scroll, drag to pan, click nodes to expand;
61
- notes open in a rendered markdown side panel.
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.
62
96
 
63
- **`/weave-view tui`** explores the same knowledge graph in the terminal: an expandable containment tree (Explore), a 1-hop neighborhood
64
- (Focus), a selected-node detail view with note/`.okf` bodies, and a staleness + link health surface all keyboard-driven and read-only.
65
- Same data as the browser viewer (the `GraphModel` assembled from vault + repo index); a pure, harness-free view-model
66
- (`src/pi/viewer/tui/model.ts`) backs the `WeaveExplorer` component. See `docs/weave-view-tui-design.md`.
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.
67
101
 
68
- 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
69
- 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.
70
106
 
71
- **`/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
72
- `.okf/repository/summaries/`, skipping files whose content hash is unchanged since their last summary. It costs tokens, so it never runs
73
- implicitly — and it runs in the background, so `/weave-scan-cancel` can stop it mid-flight.
107
+ ### The local server
74
108
 
75
- ## 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
76
122
 
77
123
  Vault note (`~/.okf/notes/auth-boundary.md`):
78
124
 
@@ -99,19 +145,50 @@ Repository index (`<repo>/.okf/`):
99
145
  └── structure.json # languages, packages, modules, entry points
100
146
  ```
101
147
 
102
- The `.okf` index is **derived**: delete it, rescan, lose nothing. By default it's excluded from git locally (`.git/info/exclude`);
103
- 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.
104
159
 
105
160
  ## For other agent harnesses
106
161
 
107
- The on-disk artifacts and `src/core` are harness-agnostic by design — Claude Code and opencode adapters are on the roadmap (docs/design.md
108
- §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 |
109
174
 
110
175
  ## Development
111
176
 
112
177
  ```bash
113
178
  npm install
114
- 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
115
184
  ```
116
185
 
117
- 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.6",
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"