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.
- package/README.md +114 -37
- package/package.json +16 -4
- package/src/core/cache/workspace.ts +466 -0
- package/src/core/frontmatter.ts +217 -23
- package/src/core/git.ts +19 -0
- package/src/core/graph/build.ts +37 -4
- package/src/core/graph/current.ts +41 -28
- package/src/core/graph/mentions.ts +170 -0
- package/src/core/graph/model.ts +24 -0
- package/src/core/index.ts +12 -0
- package/src/core/openInEditor.ts +69 -0
- package/src/core/types.ts +40 -0
- package/src/core/vault.ts +477 -43
- package/src/core/view/cluster.ts +262 -0
- package/src/core/view/detail.ts +118 -0
- package/src/core/view/focus.ts +109 -0
- package/src/core/view/health.ts +156 -0
- package/src/core/view/index.ts +15 -0
- package/src/core/view/links.ts +105 -0
- package/src/core/view/time.ts +47 -0
- package/src/core/view/tree.ts +269 -0
- package/src/core/view/types.ts +39 -0
- package/src/pi/index.ts +102 -19
- package/src/pi/viewer/tui/bodyStore.ts +98 -0
- package/src/pi/viewer/tui/branding.ts +154 -0
- package/src/pi/viewer/tui/explorer.ts +20 -31
- package/src/pi/viewer/tui/model.ts +46 -667
- package/src/pi/viewer/tui/openNote.ts +11 -0
- package/src/pi/viewer/tui/run.ts +13 -4
- package/src/pi/viewer/tui/surface/base.ts +182 -0
- package/src/pi/viewer/tui/surface/detail.ts +315 -0
- package/src/pi/viewer/tui/surface/explore.ts +206 -0
- package/src/pi/viewer/tui/surface/focus.ts +139 -0
- package/src/pi/viewer/tui/surface/health.ts +102 -0
- package/src/pi/viewer/tui/workspace.ts +381 -0
- package/src/pi/viewer/tui/workspaceRoot.ts +530 -0
- package/src/pi/viewer/web/run.ts +331 -0
- package/src/web/client/api.dom.ts +40 -0
- package/src/web/client/api.ts +472 -0
- package/src/web/client/bootstrap.ts +58 -0
- package/src/web/client/context/context.model.ts +313 -0
- package/src/web/client/dist/app.js +751 -0
- package/src/web/client/graph/Graph.tsx +158 -0
- package/src/web/client/graph/column.model.ts +431 -0
- package/src/web/client/graph/graph.model.ts +538 -0
- package/src/web/client/graph/positions.ts +339 -0
- package/src/web/client/graph/project.ts +153 -0
- package/src/web/client/graph/renderer.dom.ts +52 -0
- package/src/web/client/graph/renderer.ts +279 -0
- package/src/web/client/graph/scheme.ts +44 -0
- package/src/web/client/live.model.ts +275 -0
- package/src/web/client/live.ts +151 -0
- package/src/web/client/main.tsx +27 -0
- package/src/web/client/note/Editor.tsx +102 -0
- package/src/web/client/note/Note.tsx +113 -0
- package/src/web/client/note/editor.controller.ts +151 -0
- package/src/web/client/note/editor.model.ts +636 -0
- package/src/web/client/note/note.model.ts +738 -0
- package/src/web/client/search/SearchPalette.tsx +105 -0
- package/src/web/client/search/search.model.ts +588 -0
- package/src/web/client/search/search.ts +107 -0
- package/src/web/client/shell/Columns.tsx +161 -0
- package/src/web/client/shell/ContextRail.tsx +87 -0
- package/src/web/client/shell/Divider.tsx +44 -0
- package/src/web/client/shell/FocusTrap.tsx +56 -0
- package/src/web/client/shell/Header.tsx +54 -0
- package/src/web/client/shell/HelpOverlay.tsx +70 -0
- package/src/web/client/shell/Shell.tsx +193 -0
- package/src/web/client/shell/StatusBar.tsx +28 -0
- package/src/web/client/shell/cssvars.ts +70 -0
- package/src/web/client/shell/drag.model.ts +170 -0
- package/src/web/client/shell/focus.model.ts +100 -0
- package/src/web/client/shell/keys.model.ts +453 -0
- package/src/web/client/shell/keys.ts +59 -0
- package/src/web/client/shell/layout.model.ts +526 -0
- package/src/web/client/shell/shell.model.ts +333 -0
- package/src/web/client/shell/theme.ts +477 -0
- package/src/web/client/shell/viewport.ts +29 -0
- package/src/web/client/state.ts +78 -0
- package/src/web/client/tree/Tree.tsx +138 -0
- package/src/web/client/tree/tree.model.ts +674 -0
- package/src/web/client/workspace.ts +214 -0
- package/src/web/server/page.ts +256 -0
- package/src/web/server/routes.ts +975 -0
- package/src/web/server/security.ts +361 -0
- package/src/web/server/server.ts +275 -0
- package/src/web/server/sse.ts +321 -0
- package/src/web/server/watcher.ts +507 -0
- package/src/web/shared/graph.ts +206 -0
- package/src/web/shared/layout.ts +497 -0
- package/src/web/shared/metrics.ts +136 -0
- package/src/web/shared/view.ts +200 -0
- package/src/web/shared/wire.ts +358 -0
- package/src/pi/viewer/browser.ts +0 -29
- package/src/pi/viewer/page.ts +0 -1316
- 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
|
|
19
|
-
|
|
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
|
|
22
|
-
languages, packages, modules, entry points, and staleness state.
|
|
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
|
-
|
|
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
|
|
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
|
|
41
|
+
pi install /path/to/pi-weave # local path
|
|
36
42
|
```
|
|
37
43
|
|
|
38
|
-
|
|
44
|
+
Requires Node **>= 20.13.0**. For development against a checkout: `pi -e ./src/pi/index.ts`.
|
|
39
45
|
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
##
|
|
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`
|
|
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-
|
|
51
|
-
| Command | `/weave-scan
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
69
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
103
|
-
committing it
|
|
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
|
|
108
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
-
"
|
|
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"
|