pi-weave 0.3.0 → 0.3.2

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 (50) hide show
  1. package/README.md +40 -16
  2. package/package.json +2 -2
  3. package/src/core/frontmatter.ts +3 -3
  4. package/src/core/graph/model.ts +2 -2
  5. package/src/core/graph/wikilinks.ts +1 -1
  6. package/src/core/types.ts +1 -1
  7. package/src/pi/viewer/tui/surface/detail.ts +1 -1
  8. package/src/web/client/dist/app.js +239 -243
  9. package/src/web/client/graph/ForceTuner.tsx +14 -98
  10. package/src/web/client/graph/Graph.tsx +29 -74
  11. package/src/web/client/graph/column.model.ts +22 -15
  12. package/src/web/client/graph/graph.model.ts +31 -63
  13. package/src/web/client/graph/groups.ts +9 -7
  14. package/src/web/client/graph/positions.ts +3 -3
  15. package/src/web/client/graph/renderer.dom.ts +2 -2
  16. package/src/web/client/graph/renderer.ts +14 -5
  17. package/src/web/client/graph/tuner.model.ts +6 -180
  18. package/src/web/client/main.tsx +1 -4
  19. package/src/web/client/note/Note.tsx +77 -92
  20. package/src/web/client/note/drafts.ts +172 -0
  21. package/src/web/client/note/note.model.ts +2 -34
  22. package/src/web/client/search/SearchPalette.tsx +9 -8
  23. package/src/web/client/shell/ContextRail.tsx +8 -9
  24. package/src/web/client/shell/Settings.tsx +71 -0
  25. package/src/web/client/shell/Shell.tsx +409 -255
  26. package/src/web/client/shell/StatusBar.tsx +2 -6
  27. package/src/web/client/shell/focus.model.ts +2 -2
  28. package/src/web/client/shell/keys.model.ts +40 -39
  29. package/src/web/client/shell/keys.ts +1 -0
  30. package/src/web/client/shell/shell.model.ts +32 -128
  31. package/src/web/client/shell/theme.model.ts +27 -97
  32. package/src/web/client/shell/theme.ts +32 -238
  33. package/src/web/client/shell/workspace.css.ts +140 -0
  34. package/src/web/client/tree/Tree.tsx +43 -14
  35. package/src/web/client/tree/tree.model.ts +19 -0
  36. package/src/web/client/workspace.ts +19 -1
  37. package/src/web/server/backup.ts +59 -0
  38. package/src/web/server/routes.ts +45 -3
  39. package/src/web/server/server.ts +5 -0
  40. package/src/web/server/workspace-state.ts +121 -0
  41. package/src/web/shared/layout.ts +5 -6
  42. package/src/web/shared/preferences.ts +76 -0
  43. package/src/web/shared/themes.ts +92 -0
  44. package/src/web/shared/workspace.ts +310 -0
  45. package/src/web/client/selection.storage.ts +0 -69
  46. package/src/web/client/shell/Columns.tsx +0 -139
  47. package/src/web/client/shell/Divider.tsx +0 -15
  48. package/src/web/client/shell/Header.tsx +0 -119
  49. package/src/web/client/shell/drag.model.ts +0 -35
  50. package/src/web/client/shell/layout.model.ts +0 -132
package/README.md CHANGED
@@ -154,22 +154,46 @@ Renaming or moving a note rewrites its inbound links automatically, so its backl
154
154
  /weave-view tui # Pi only: terminal UI for SSH or browser-free use
155
155
  ```
156
156
 
157
- The browser workspace has four connected views:
158
-
159
- - **Tree** — notes, folders, and repository structure, with text and provenance filters.
160
- - **Note** — rendered Markdown with clickable `[[wikilinks]]`, link previews, tags, authorship, click-to-edit, and an action to open the
161
- source in `$EDITOR`.
162
- - **Graph** — a navigable map of notes, links, mentions, modules, and repository relationships. Selecting something updates every view.
163
- - **Context** — links, backlinks, tags, and code mentions for the current selection.
164
-
165
- Search with `⌘K` / `Ctrl K`. Press `?` for all shortcuts. The workspace updates as notes change on disk, so a note written by Pi appears
166
- without a reload. It follows the system theme by default and can be switched between light and dark.
167
-
168
- **Click the note text to edit it** — the prose swaps for its Markdown source; `⌘S` / `Ctrl S` saves, `Esc` or **Done** closes. Selecting
169
- text to copy and clicking a `[[wikilink]]` do what they always did; neither opens the editor. A save rewrites the body and nothing
170
- else — unknown front-matter fields, key order, and the append-only `## Raw` tail of a dictated note all survive untouched, so a note edited
171
- here and a note edited in Obsidian stay byte-compatible. Editing with `$EDITOR`, Obsidian, or the `weave_note` tool works as before; the
172
- last writer wins, and the workspace picks up outside changes within a couple of seconds.
157
+ The browser workspace puts notes at the center, with a collapsible notes sidebar, document tabs, and optional context for links,
158
+ backlinks, tags, and code mentions. Open a note to replace the current document; `⌘` / `Ctrl` click a note or wiki-link to open a new tab.
159
+ Drag a tab title within its tab strip to reorder tabs, or use `Alt ←` / `Alt →` while the tab is focused.
160
+ Each document tab has its own Back/Forward history and reading position. The tab strip sits at the top of the workspace.
161
+ Use the ribbon search button or `⌘K` / `Ctrl K`; `⌘` / `Ctrl Enter` opens a result
162
+ in a new tab. **Recent** keeps its order while you browse; returning to it refreshes the visit order. Its rows show the same item icons
163
+ as Files. Press `?` for shortcuts.
164
+
165
+ Open **Graph view** from the left ribbon. Click a node to preview its title and type while staying in Graph. Click the same node again
166
+ or choose **Open in new tab** to open its content; in a split layout, the new tab opens in the other pane. Dragging does not open content.
167
+ Use **Pane options (···)** to split right or down, move the current tab to the other pane, or close a pane while retaining its tabs.
168
+ In a split workspace, drag a tab title into the other pane to move it. History, reading position, and unsaved drafts stay with it. On small windows, **Switch pane** reaches the
169
+ other group. Drag a note from Files into either pane to open it in a new tab. Closing or moving the last tab out of a split removes that pane;
170
+ closing the final workspace tab leaves a New tab. `Option W` / `Alt W` closes the active Weave tab using the same unsaved-draft guard.
171
+ Some browser hosts also claim this shortcut: Codex’s in-app browser still closes its outer tab. Both sidebars can be shown or hidden from the ribbon.
172
+
173
+ Click **Edit** to change a note's Markdown; `⌘S` / `Ctrl S` saves, and **Done** closes the editor. Drafts survive tab and pane switching,
174
+ and duplicate views of a note share one draft. Closing or replacing the last view of an unsaved note asks before discarding it. A save
175
+ rewrites only the body: unknown front-matter fields, key order, and the append-only `## Raw` tail survive untouched. Outside edits appear
176
+ within a couple of seconds; the last writer wins.
177
+
178
+ Tabs, pane sizes, sidebars, theme, and reading positions restore for the same vault and repository, even when the local server port
179
+ changes. Presentation snapshots live under `$XDG_CONFIG_HOME/pi-weave/presentation` (or `~/.config/pi-weave/presentation`), separate from
180
+ the knowledge files. Unsaved text stays in memory and is guarded on reload/close; it is not restored after closing the browser. Missing
181
+ notes do not prevent the other tabs from restoring. The workspace follows the system theme unless you choose a palette in Settings.
182
+
183
+ Open **Settings** with the gear button or `⌘,` / `Ctrl ,`. General includes workspace locations, refresh, documentation, and
184
+ keyboard shortcuts. Appearance offers six Catppuccin palettes and three additional light/dark pairs, an independent accent selector,
185
+ and note font size. Choose a light theme and a dark theme; the ribbon button and `t` switch between those two. System mode follows
186
+ your device using the selected pair. Interface holds sidebar visibility, group colors, and the live graph layout sliders. Editor controls spellcheck,
187
+ readable line length, and whether newly opened notes start in editing mode. Files controls startup tabs and whether new tabs take focus.
188
+ These preferences are stored with the workspace snapshots.
189
+
190
+ **Settings → Backup → Download vault ZIP** exports saved vault files, including attachments, hidden metadata, empty folders, and linked
191
+ content. Save unsaved drafts before downloading. Backups are manual; there is no scheduled backup or sync. Restore by extracting the ZIP
192
+ into a vault directory. Symbolic-link cycles, unreadable files, and entries outside ZIP format limits produce an error instead of a partial
193
+ archive. Presentation snapshots and the separate repository index are not part of the vault download.
194
+
195
+ This browser facelift is the first stage toward a dedicated macOS window. `/weave-view` still launches the browser, and the agent owns
196
+ the local server's lifetime.
173
197
 
174
198
  `/weave-view tui` is the smaller, read-only terminal explorer: tree, focused neighborhood, details, and link health over the same graph.
175
199
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-weave",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
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,
@@ -18,7 +18,6 @@
18
18
  "local-first",
19
19
  "knowledge-graph",
20
20
  "codebase-memory",
21
- "obsidian",
22
21
  "developer-tools"
23
22
  ],
24
23
  "license": "MIT",
@@ -94,6 +93,7 @@
94
93
  "vitest": "^3.2.4"
95
94
  },
96
95
  "dependencies": {
96
+ "fflate": "^0.8.3",
97
97
  "zod": "4.1.8"
98
98
  }
99
99
  }
@@ -14,7 +14,7 @@ import { NOTE_SOURCES } from "./types";
14
14
  * not the same promise. `parseNoteFile` read five keys and `serializeNote`
15
15
  * wrote five keys, so every write through core silently deleted whatever
16
16
  * else the file carried — `aliases`, `cssclass`, `publish`, any property an
17
- * Obsidian user or another tool had added. Reading a note and appending one
17
+ * external editor or another tool had added. Reading a note and appending one
18
18
  * line destroyed the rest of its metadata (weave-workspace §11 P5).
19
19
  *
20
20
  * The fix is *not* a fuller YAML parser. A vault is plain text a human edits,
@@ -46,8 +46,8 @@ import { NOTE_SOURCES } from "./types";
46
46
  * change rather than a silent one. See {@link isDefaulted}.
47
47
  *
48
48
  * **An owned key whose on-disk syntax this subset cannot represent is
49
- * frozen**: carried verbatim, and not re-rendered or duplicated. Obsidian's
50
- * property editor writes tags as a YAML block list —
49
+ * frozen**: carried verbatim, and not re-rendered or duplicated. A property
50
+ * editor may write tags as a YAML block list —
51
51
  *
52
52
  * ```yaml
53
53
  * tags:
@@ -64,8 +64,8 @@ export interface GraphModel {
64
64
  * slug → wiki-link targets that resolved to no note in the graph
65
65
  * (weave-workspace §4.2).
66
66
  *
67
- * A `[[target]]` that matches nothing is not an error — it is Obsidian's
68
- * ghost node, the affordance that offers to create the missing note. The
67
+ * A `[[target]]` that matches nothing is not an error — it is a ghost node,
68
+ * the affordance that offers to create the missing note. The
69
69
  * builder used to count these and throw the names away, leaving
70
70
  * `detail["dangling links"] = "3"` as the only trace; a display string is
71
71
  * not something a UI can navigate.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Obsidian-compatible [[wiki-link]] extraction from note bodies.
2
+ * Wiki-link extraction from note bodies.
3
3
  * Pure module used by graph construction and viewer view-models.
4
4
  */
5
5
 
package/src/core/types.ts CHANGED
@@ -29,7 +29,7 @@ export interface NoteMeta {
29
29
  * This is how pi-weave keeps front matter **lossless**. `NoteMeta` names the
30
30
  * five fields the engine understands; a vault is a directory of files a human
31
31
  * also edits, so real notes carry keys the engine has never heard of —
32
- * Obsidian's `aliases`, `cssclass`, `publish`, whatever the user invented last
32
+ * `aliases`, `cssclass`, `publish`, whatever the user invented last
33
33
  * Tuesday. Modelling those as parsed values would mean re-emitting them, and
34
34
  * re-emitting a value the parser only half-understands is how formatting (and
35
35
  * then content) gets destroyed.
@@ -148,7 +148,7 @@ export class DetailSurface implements Surface {
148
148
  if (matchesKey(data, "enter")) {
149
149
  const row = this.activeRow();
150
150
  if (row?.target) {
151
- // rebind this detail pane to the target (Obsidian "open in main" in place)
151
+ // rebind this detail pane to the target (open in main, in place)
152
152
  this.state = { nodeId: row.target, selectedId: row.target, scrollOffset: 0, gotoBuf: null };
153
153
  this._lines = undefined;
154
154
  this.requestBody(row.target);