@marver-design/marver 0.15.0 → 0.16.0

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 (33) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/README.md +2 -1
  3. package/dist/boards-6hKVW42a.mjs +57 -0
  4. package/dist/boards-BdG1TJwU.mjs +267 -0
  5. package/dist/{build-DfuTQZlY.mjs → build-Ct0iMoSi.mjs} +68 -29
  6. package/dist/cli.mjs +13 -4
  7. package/dist/{daemon-DalgvoA9.mjs → daemon-Cb4JjpgL.mjs} +1 -1
  8. package/dist/{dev-BxCmeU_H.mjs → dev-CdcIuhZJ.mjs} +4 -4
  9. package/dist/{init-QKNi9gvF.mjs → init-BQIpIpIv.mjs} +6 -3
  10. package/dist/{manifest-BzxSMoDB.mjs → manifest-CpbsqQ_v.mjs} +77 -11
  11. package/dist/{plugin-DJyjmQeh.mjs → plugin-BXyezwfN.mjs} +164 -69
  12. package/dist/{poster-CbpzSzJu.mjs → poster-DOY7pax8.mjs} +1 -1
  13. package/dist/{shot-BWhoz6cU.mjs → shot-CwmHO5T4.mjs} +2 -2
  14. package/docs/publish.md +4 -1
  15. package/package.json +1 -1
  16. package/src/client/shell/App.tsx +4 -246
  17. package/src/client/shell/BoardList.tsx +408 -0
  18. package/src/client/shell/ContextMenu.tsx +59 -0
  19. package/src/client/shell/icons.tsx +6 -0
  20. package/src/client/shell/store.ts +105 -47
  21. package/src/client/shell/styles.css +36 -4
  22. package/src/shared/board-tree.ts +285 -0
  23. package/templates/AGENTS-embedded.md +18 -5
  24. package/templates/AGENTS-studio.md +18 -5
  25. package/templates/instructions/boards.md +73 -2
  26. package/templates/instructions/craft.md +4 -0
  27. package/templates/instructions/discover.md +7 -2
  28. package/templates/instructions/iterate.md +5 -4
  29. package/templates/instructions/review.md +4 -0
  30. package/templates/instructions/shape.md +1 -1
  31. package/templates/instructions/welcome.md +4 -1
  32. package/templates/instructions/wireframe.md +3 -0
  33. package/dist/{comments-DHB_8BRa.mjs → comments-oYcZ3cE-.mjs} +1 -1
@@ -10,9 +10,14 @@ viewport and lays it out:
10
10
 
11
11
  ```json
12
12
  { "version": 1, "name": "checkout-compare", "order": 1, "auto": false,
13
+ "description": "Cart step, direction A vs B side by side - B is the current favourite",
13
14
  "nodes": [ { "frame": "checkout-a/cart" }, { "frame": "checkout-b/cart" } ] }
14
15
  ```
15
16
 
17
+ - `description` - one sentence on what the board is for and where it stands. It is
18
+ how a later session (or the human's next agent) knows this board without opening
19
+ it; it lands in design/manifest.json. Write it at creation, keep it true.
20
+
16
21
  - The same frame may appear on many boards, or twice on one (add `"w"`/`"h"` on a
17
22
  node to pin a size, `"x"`/`"y"` to place it - e.g. a comparison row: same `y`,
18
23
  increasing `x`).
@@ -23,8 +28,8 @@ viewport and lays it out:
23
28
  orienting board (an overview or the primary flow) - never a giant one. Boards
24
29
  without an `order` sort after the ranked ones, by name. Set `order` deliberately on
25
30
  every curated board; it is the first impression. The human can also drag-reorder boards
26
- in the sidebar (which rewrites `order`) and rename one from its right-click menu - so
27
- your ranking is a starting point they may adjust.
31
+ in the sidebar (which rewrites `order`), rename one from its right-click menu, and file
32
+ boards into folders (below) - so your ranking is a starting point they may adjust.
28
33
  - `auto: false` boards show exactly their list. `all-scenes` is auto-managed (it holds
29
34
  EVERY frame, so it is the heavy one) and always sinks to the BOTTOM of the switcher -
30
35
  never the landing board, and never write its file.
@@ -44,6 +49,72 @@ viewport and lays it out:
44
49
  version, oldest at the top. Winners live on the feature boards; the archive
45
50
  answers "what did we try?" and "what did it look like before?".
46
51
 
52
+ ## Folders - organising the sidebar
53
+
54
+ Boards can sit in folders, one level deep (folders hold boards, never folders).
55
+ Files are the truth, and two files carry it:
56
+
57
+ - **Membership lives on the board**: `"folder": "research"` in the board file, next
58
+ to `order`. `order` then ranks the board among its folder siblings (root boards and
59
+ folders share the root sequence). Same grammar as board names
60
+ (`^[a-z0-9][a-z0-9-]*$`); an invalid value means top level. `all-scenes` never
61
+ lives in a folder.
62
+ - **Folders live in `design/boards/_folders.json`** - the underscore marks it as
63
+ infrastructure, never a board:
64
+
65
+ ```json
66
+ { "version": 1, "folders": [
67
+ { "name": "research", "order": 1, "description": "The thinking behind the live boards - specs, flows, references" },
68
+ { "name": "archive", "order": 3, "description": "Retired directions and scene versions, oldest first" } ] }
69
+ ```
70
+
71
+ A folder's `description` says what belongs in it - the next session files boards
72
+ right without asking.
73
+
74
+ It exists so an EMPTY folder can exist and so a folder has a rank at the root.
75
+ A folder a board names but the registry lacks is still real (it sorts after the
76
+ ranked items, by name) - two boards with `"folder": "research"` make a Research
77
+ folder on their own. A malformed registry is an error the canvas shows, not an
78
+ empty one - fix it, never delete it.
79
+
80
+ **Look before you organise: `npx marver boards`** prints the sidebar as the files say
81
+ it is - every folder (and whether it is empty or only implied by its boards), every
82
+ board in reading order with its `order`, the landing board, and whether the registry
83
+ exists (`--json` for the tree). Run it before any of the moves below; the human may
84
+ have rearranged things since you last looked, and their arrangement stands.
85
+
86
+ The moves, each a file edit, so the files always agree:
87
+ - **Create** a folder: add `{ "name": "<slug>", "order": <n>, "description": "…" }`
88
+ to the registry's `folders` (create the file if absent) - or just point a board at it.
89
+ - **Move a board in**: write `"folder": "<slug>"` on the board and give it an `order`
90
+ among that folder's boards. **Move it out**: delete the `folder` field and give it
91
+ an `order` among the top-level items.
92
+ - **Rank** folders and boards: `order` on the board (among its siblings) and on the
93
+ registry entry (among the top-level items). Renumber the siblings you touch.
94
+ - **Rename** a folder: rewrite `folder` on every member AND the registry entry - a
95
+ registry rename alone leaves the members in the old (implied) folder.
96
+ - **Delete** a folder: remove `folder` from every member, then its registry entry.
97
+ Folders organise, never own: deleting one never deletes a board.
98
+ - The **landing board** is the first board in sidebar order, folders included -
99
+ rank a folder first and its first board opens the canvas.
100
+
101
+ Use folders proactively, the way a tidy studio would: a canvas past six or eight
102
+ boards wants grouping - the live feature boards at the top level, `research` /
103
+ `specs` for the thinking, `decks` for slides, `archive` for history and versions
104
+ last. Propose the grouping in one sentence and do it; keep folder names short and
105
+ plain.
106
+
107
+ The human does all of this too - from the sidebar: New folder (right-click the Boards
108
+ header, or its `+`), Rename, Delete folder, "Move to …" on a board, and DRAG: boards
109
+ into and out of folders, folders among boards. Each drag rewrites `order` (and
110
+ `folder`) on the boards it touches and the registry - the shell owns those fields
111
+ while the canvas is open, exactly as it owns `order`; write membership and new
112
+ folders freely, and never rewrite an arrangement the human just made. The shell
113
+ refuses a write that would overwrite an edit it has not seen (your file write and
114
+ the human's drag can never silently erase each other), so read a board file before
115
+ you rewrite it. Published canvases show the folders of the published boards only; a
116
+ folder with nothing published never reaches the bundle.
117
+
47
118
  ## The default composition: one horizontal band
48
119
 
49
120
  A board reads like a page: left to right first, down only for a reason. The
@@ -144,6 +144,10 @@ app, and the human attributes the fault to your frame, not to a library.
144
144
 
145
145
  ## Frame law
146
146
 
147
+ - Every frame carries `meta.description` - one sentence, what the screen is for and
148
+ its state when that is not obvious ("Filled state of the orders table, current
149
+ direction"). It reaches design/manifest.json; the next session reads it instead
150
+ of the file.
147
151
  - Frames are made of the app's real components and tokens. Rebuilding a lookalike of
148
152
  an existing component inside a frame is a defect.
149
153
  - Repeated and semantic values (colors, type sizes, radii, the spacing rhythm)
@@ -40,12 +40,17 @@ to the SURFACE, not the product.
40
40
 
41
41
  Create `design/scenes/<scene>/_brief.md`: audience + scene, the one job, mode, the
42
42
  flow as a numbered list, content sources, out-of-scope. Ten lines, not a document.
43
+ **Its first non-blank line is the scene's one-sentence description** - purpose and state,
44
+ e.g. `# Checkout - the buyer's path from cart to receipt (v2, after the pricing pivot)`.
45
+ That line lands in `design/manifest.json` as the scene's `description`, so a later
46
+ session reads it without opening the brief; keep it true as the scene moves on (a
47
+ scene that only needs a gist - a version snapshot, an archive - gets a one-line brief).
43
48
  Show it. Get the nod.
44
49
 
45
50
  **Unattended?** When the human is away or has said "don't ask", the interview and
46
51
  the nod convert to obligations, not blockers: answer the five questions yourself
47
- from the repo and reasonable product judgment, mark the brief `UNCONFIRMED` at the
48
- top, proceed - and surface the brief FIRST when the human returns. Never stall on
52
+ from the repo and reasonable product judgment, mark the brief `UNCONFIRMED` in its
53
+ first line (`# Checkout - … (UNCONFIRMED)`), proceed - and surface the brief FIRST when the human returns. Never stall on
49
54
  an absent human; never hide that the brief was self-answered.
50
55
 
51
56
  ## 4. Align on flow with a diagram frame
@@ -113,11 +113,12 @@ The human picks a direction; then, in one pass:
113
113
  1. **The winner takes the clean name.** Drop its letter prefix (or promote it
114
114
  over the original file); update goto targets pointing at old ids.
115
115
  2. **The losers move to `design/scenes/archive/`** - never deleted, RELABELED:
116
- filename `<feature>-<direction>.tsx`, meta.title saying exactly what it was
117
- and why it retired, e.g.
118
- `{ title: "Routines editor - guided steps (retired: sentence canvas won, sharper mental model)" }`.
116
+ filename `<feature>-<direction>.tsx`, meta.title saying what it was and
117
+ meta.description saying why it retired, e.g.
118
+ `{ title: "Routines editor - guided steps", description: "Retired: the sentence canvas won - sharper mental model" }`.
119
119
  A one-line comment at the top of the file carries any longer why. That
120
- sentence is the learning - write it while the reason is fresh.
120
+ sentence is the learning - write it while the reason is fresh; it reaches
121
+ design/manifest.json, so the next session knows without opening the file.
121
122
  3. **The `archive` board stays clean and organized:** a curated board over the
122
123
  archive scene, tidied with a layout recipe, grouped by feature. Anyone
123
124
  opening it should know what every frame was without asking.
@@ -26,6 +26,10 @@ however late it surfaced.
26
26
  6. **States exist**: for each screen with meaningful states, the empty / error /
27
27
  loading siblings are present and reachable.
28
28
  7. **Craft floor**: one pass over craft.md's Verify list against the RENDERED frames.
29
+ 8. **Descriptions true**: read design/manifest.json once more - every board, folder,
30
+ scene and frame this session touched carries a `description` that is still true
31
+ (state words above all: retired, winning, superseded). The next session orients
32
+ from that file; a stale sentence there costs it more than a missing one.
29
33
 
30
34
  ## Honesty rules
31
35
 
@@ -60,7 +60,7 @@ detection is lexical), and declare `intent` on every content frame:
60
60
  ```tsx
61
61
  import { Doc, Row, Col, Md, Diagram, Img, Chart } from '@marver-design/marver/content'
62
62
 
63
- export const meta = { title: 'Checkout - how it works', intent: 'diagram' }
63
+ export const meta = { title: 'Checkout - how it works', intent: 'diagram', description: 'The agreed flow, five screens - the source for the wireframes' }
64
64
 
65
65
  export default () => (
66
66
  <Doc layout="wide">
@@ -61,7 +61,10 @@ without narrating into the void; your next message is the reveal.
61
61
  State your understanding of the product in 2-3 sentences, ask "did I get
62
62
  that right?" - then STOP: no further tool calls, end your turn, resume when
63
63
  the human replies. (Only exception: they explicitly asked for unattended
64
- execution - assume, mark UNCONFIRMED, surface it first.)
64
+ execution - assume, mark UNCONFIRMED, surface it first.) Once they confirm,
65
+ write that understanding as one sentence into `description` in
66
+ design/config.ts - the project's line in design/manifest.json, the first
67
+ thing every later session reads.
65
68
  2. **Confirm the stack aloud - what detection ACTUALLY found.** Read AGENTS.md's
66
69
  UI line and design/theme.css and narrate the reality, for example: "Tailwind
67
70
  + shadcn/ui; brand tokens in <file>; design/theme.css imports them." No
@@ -14,6 +14,9 @@ lands on what is actually being decided.
14
14
 
15
15
  ## The rules (strict)
16
16
 
17
+ 0. **Every frame says what it is.** `meta.title` and `meta.description` (one sentence:
18
+ the screen's job, and "wireframe" while it is one) - the manifest carries them, so
19
+ a later session knows the lo-fi from the hi-fi without opening files.
17
20
  1. **Throwaway code is correct here.** Plain divs, inline layout, one file per frame.
18
21
  Do NOT build proper components for wireframes and do NOT touch the app's
19
22
  `components/` directory - lo-fi structure hardening into real components is how
@@ -4,8 +4,8 @@ import { i as readLog, r as listBoards, t as appendEvents } from "./comments-DZy
4
4
  import { a as syncOnce, i as loadCollab, n as connectClaim, r as connectToken, t as connect } from "./sync-BZaCWqK-.mjs";
5
5
  import { n as localProfile } from "./profile-BjAPAJSb.mjs";
6
6
  import { join } from "node:path";
7
- import { createInterface } from "node:readline";
8
7
  import { randomUUID } from "node:crypto";
8
+ import { createInterface } from "node:readline";
9
9
  //#region src/cli/comments.ts
10
10
  /**
11
11
  * `marver comments <action>` - the collaboration CLI.