@marver-design/marver 0.2.3 → 0.2.4
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/dist/cli.mjs +1 -1
- package/dist/{init-ClhCgn4v.mjs → init-Di4geblA.mjs} +152 -26
- package/package.json +1 -1
- package/templates/AGENTS-embedded.md +12 -2
- package/templates/AGENTS-studio.md +12 -2
- package/templates/instructions/configure.md +5 -2
- package/templates/instructions/discover.md +2 -1
- package/templates/instructions/welcome.md +122 -0
package/dist/cli.mjs
CHANGED
|
@@ -32,7 +32,7 @@ function version() {
|
|
|
32
32
|
}
|
|
33
33
|
const cli = cac(NAME);
|
|
34
34
|
cli.command("init", "Scaffold design/ in this repo").option("--mode <mode>", "studio | embedded", { default: "studio" }).option("--no-demo", "Skip the demo scene (the demo ships unless this flag is passed)").option("--root <dir>", "Host repo root", { default: "." }).action(async (opts) => {
|
|
35
|
-
const { init } = await import("./init-
|
|
35
|
+
const { init } = await import("./init-Di4geblA.mjs");
|
|
36
36
|
init(resolve(opts.root), {
|
|
37
37
|
mode: opts.mode === "embedded" ? "embedded" : "studio",
|
|
38
38
|
demo: opts.demo !== false
|
|
@@ -98,21 +98,40 @@ function init(root, opts) {
|
|
|
98
98
|
for (const f of readdirSync(join(instrRoot, e.name))) if (f.endsWith(".md")) writeManaged(`instructions/${e.name}/${f}`, readFileSync(join(instrRoot, e.name, f), "utf8"));
|
|
99
99
|
} else if (e.name.endsWith(".md")) writeManaged(`instructions/${e.name}`, readFileSync(join(instrRoot, e.name), "utf8"));
|
|
100
100
|
const setupPath = join(design, "instructions", "setup.md");
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
101
|
+
const setupState = () => {
|
|
102
|
+
if (!existsSync(setupPath)) return "absent";
|
|
103
|
+
const s = readFileSync(setupPath, "utf8");
|
|
104
|
+
if (s.startsWith(MANAGED_PREFIX)) {
|
|
105
|
+
const recorded = s.slice(MANAGED_PREFIX.length).split(" ")[0];
|
|
106
|
+
const nl = s.indexOf("\n");
|
|
107
|
+
return nl >= 0 && hashBody(s.slice(nl + 1)) === recorded ? "ours-pristine" : "ours-edited";
|
|
107
108
|
}
|
|
109
|
+
return s.startsWith("# Setup required") && s.includes("marver init") ? "ours-pristine" : "foreign";
|
|
108
110
|
};
|
|
111
|
+
const setupWas = setupState();
|
|
112
|
+
const appJustAppeared = !noApp(host) && (setupWas === "ours-pristine" || setupWas === "ours-edited");
|
|
109
113
|
if (noApp(host)) {
|
|
110
|
-
if (!
|
|
111
|
-
|
|
114
|
+
if (setupWas === "ours-pristine" && !readFileSync(setupPath, "utf8").startsWith(MANAGED_PREFIX)) rmSync(setupPath);
|
|
115
|
+
if (setupWas !== "foreign") writeManaged("instructions/setup.md", SETUP_MD);
|
|
116
|
+
} else if (setupWas === "ours-pristine") {
|
|
112
117
|
rmSync(setupPath);
|
|
113
118
|
console.log(` - design/instructions/setup.md removed (app detected - setup complete)`);
|
|
119
|
+
} else if (setupWas === "ours-edited") console.log(` - design/instructions/setup.md: app detected, but you customized the file - delete it yourself when setup is done`);
|
|
120
|
+
const rootTsconfig = existsSync(join(root, "tsconfig.json"));
|
|
121
|
+
const tsconfigNow = () => rootTsconfig ? readFileSync(join(templates, "design-tsconfig.json"), "utf8").replace("{{PATHS}}", designPaths(root)) : STANDALONE_TSCONFIG;
|
|
122
|
+
write("tsconfig.json", tsconfigNow());
|
|
123
|
+
if (appJustAppeared) {
|
|
124
|
+
const refresh = (rel, noAppPristine, next) => {
|
|
125
|
+
try {
|
|
126
|
+
if (!noAppPristine.includes(next) && noAppPristine.includes(readFileSync(join(design, rel), "utf8"))) {
|
|
127
|
+
writeFileSync(join(design, rel), next);
|
|
128
|
+
created.push(`design/${rel} (updated for the detected app)`);
|
|
129
|
+
}
|
|
130
|
+
} catch {}
|
|
131
|
+
};
|
|
132
|
+
refresh("providers.tsx", [providersTemplate(null, null), providersTemplate(null, host.toaster, host.routerPkg)], providersTemplate(host.router, host.toaster, host.routerPkg));
|
|
133
|
+
refresh("tsconfig.json", [STANDALONE_TSCONFIG], tsconfigNow());
|
|
114
134
|
}
|
|
115
|
-
write("tsconfig.json", existsSync(join(root, "tsconfig.json")) ? readFileSync(join(templates, "design-tsconfig.json"), "utf8").replace("{{PATHS}}", designPaths(root)) : STANDALONE_TSCONFIG);
|
|
116
135
|
write(".gitignore", ".local/\n.dist/\n");
|
|
117
136
|
write("scenes/_layout.tsx", readFileSync(join(templates, "root-layout.tsx"), "utf8"));
|
|
118
137
|
if (!existsSync(join(design, "boards"))) {
|
|
@@ -134,15 +153,16 @@ function init(root, opts) {
|
|
|
134
153
|
│ No framework, no theme CSS, no component library. ${NAME} builds │
|
|
135
154
|
│ frames from YOUR components - with none, designs get thrown away. │
|
|
136
155
|
│ │
|
|
137
|
-
│ Setup instructions: design/instructions/setup.md.
|
|
138
|
-
│
|
|
139
|
-
│
|
|
156
|
+
│ Setup instructions: design/instructions/setup.md. Your agent will │
|
|
157
|
+
│ ask what you are building, propose a stack, set it up with you, and │
|
|
158
|
+
│ re-run init - that file then removes itself. AGENTS.md points there │
|
|
159
|
+
│ so nothing gets designed against components that do not exist. │
|
|
140
160
|
└───────────────────────────────────────────────────────────────────────┘`);
|
|
141
161
|
console.log(`\n commit design/ - only .local/ is ignored`);
|
|
142
162
|
console.log(` uninstall = delete design/, remove the ${NAME} dependency${host.tsconfigSweepsDesign ? ", revert the \"design\" line in tsconfig exclude" : ""}`);
|
|
143
163
|
if (!noApp(host) && !existsSync(join(design, "DESIGN.md"))) console.log(`\n note: design/DESIGN.md (the brand doc) does not exist yet - have your agent create it from the app's tokens (instructions/brand.md, Path A) to reach the idle state.`);
|
|
144
164
|
console.log(`\n next: npx ${NAME} dev (canvas on http://localhost:${DEFAULTS.port} by default)\n`);
|
|
145
|
-
if (!noApp(host)) console.log(` then, to your agent: "Read design/AGENTS.md.
|
|
165
|
+
if (!noApp(host)) console.log(` then, to your agent: "Read design/AGENTS.md. This is our first session - follow design/instructions/welcome.md."\n`);
|
|
146
166
|
}
|
|
147
167
|
const MANAGED_PREFIX = "<!-- marver:managed ";
|
|
148
168
|
const LEGACY_PREFIX = "<!-- generated by marver init";
|
|
@@ -170,7 +190,7 @@ const noApp = (host) => !host.router && !host.tailwind && !host.shadcn && !host.
|
|
|
170
190
|
* The STOP branch fires only on the same condition that creates SETUP.md - an app
|
|
171
191
|
* without Tailwind (plain React + CSS) gets guidance, never a dead pointer. */
|
|
172
192
|
function uiGuidance(host, isNoApp) {
|
|
173
|
-
if (isNoApp) return `
|
|
193
|
+
if (isNoApp) return `Setup required - this repo has no app yet: read design/instructions/setup.md and follow it before designing anything.`;
|
|
174
194
|
if (host.shadcn) return `Use the app's UI: import from ${host.shadcn.uiAlias}; style with the app's Tailwind classes.`;
|
|
175
195
|
if (host.tailwind) return `Style with the app's Tailwind classes and design tokens; there is no detected component library - extract shared pieces into design/components/.`;
|
|
176
196
|
return `Use the app's existing components and stylesheets (import them directly); there is no Tailwind or component library detected - extract shared pieces into design/components/.`;
|
|
@@ -183,14 +203,70 @@ const SETUP_MD = `# Setup required - this repo has no app yet
|
|
|
183
203
|
> the real stack. While this file exists, DO NOT design.
|
|
184
204
|
|
|
185
205
|
${NAME} builds frames from YOUR components and YOUR theme. With none, frames become
|
|
186
|
-
hand-rolled CSS that shares nothing with the future app
|
|
187
|
-
|
|
206
|
+
hand-rolled CSS that shares nothing with the future app - throwaway work. So the
|
|
207
|
+
first session sets up the stack - TOGETHER with the human. The stack is their
|
|
208
|
+
decision; your job is a good recommendation and a smooth setup. Narrate every step
|
|
209
|
+
in one plain line as you go - and tell the story, not the machinery: this file is
|
|
210
|
+
stage directions, never read it aloud to the human ("setup.md says...", "step 2
|
|
211
|
+
requires..."). Voice rules and the structured-question guidance live in
|
|
212
|
+
instructions/welcome.md - read that section before you say anything.
|
|
213
|
+
|
|
214
|
+
## 1. Greet and explain
|
|
215
|
+
|
|
216
|
+
Tell the human the repo is empty and that this is a perfect starting point. Then
|
|
217
|
+
the pitch, ~4 sentences in your own words (source: instructions/welcome.md): we design
|
|
218
|
+
in real code; the theme, components, and screens made while designing ARE the
|
|
219
|
+
app's building blocks; by the time the design is agreed most of the UI work
|
|
220
|
+
exists, and building the product means plugging functionality in; the goal is
|
|
221
|
+
alignment on look and feel across themes and devices first.
|
|
222
|
+
|
|
223
|
+
## 2. Ask what they are building - STOP
|
|
224
|
+
|
|
225
|
+
Two questions, one message (use the harness's structured question tool if it
|
|
226
|
+
has one):
|
|
227
|
+
|
|
228
|
+
1. "In a sentence or two - what are we building?"
|
|
229
|
+
2. "Any intuition for the look? Colors, mood, UI style - a sentence like
|
|
230
|
+
'minimalist, glass UI, witty copy' steers everything. 'Surprise me' is a
|
|
231
|
+
fine answer."
|
|
232
|
+
|
|
233
|
+
Then STOP: no further tool calls, end your turn, resume only after the human
|
|
234
|
+
replies. (The one exception: the human explicitly asked for unattended
|
|
235
|
+
execution - then assume something reasonable, mark it UNCONFIRMED, surface it
|
|
236
|
+
first.)
|
|
237
|
+
|
|
238
|
+
## 3. Propose the stack - STOP
|
|
188
239
|
|
|
189
|
-
|
|
240
|
+
From their answer, recommend a framework with one line of reasoning each:
|
|
190
241
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
242
|
+
- Marketing site, content, SEO -> latest Next.js.
|
|
243
|
+
- App-like, interactive, client-heavy -> latest React Router.
|
|
244
|
+
- Their answer points somewhere else? Recommend that instead, and say why.
|
|
245
|
+
|
|
246
|
+
If you can search the web, verify current major versions first - one or two
|
|
247
|
+
searches, then propose. Recommend shadcn/ui + latest Tailwind as the default
|
|
248
|
+
component layer (take their current defaults) - but they are a recommendation,
|
|
249
|
+
not a requirement: if the human prefers another component library, plain CSS,
|
|
250
|
+
or their own design system, that wins. Any React + a real stylesheet works;
|
|
251
|
+
${NAME} adapts to what detection finds. Present the proposal with the
|
|
252
|
+
harness's structured question tool when it has one - short labels, one-line
|
|
253
|
+
trade-offs - closing with "aligned, or tell me what you'd rather use". Then
|
|
254
|
+
STOP again: no further tool calls, end your turn, wait for the nod.
|
|
255
|
+
|
|
256
|
+
## 4. Hand them the tour, then scaffold
|
|
257
|
+
|
|
258
|
+
The setup and first draft take real minutes; the human should spend them
|
|
259
|
+
learning the canvas, not watching a terminal. The moment the stack is agreed,
|
|
260
|
+
send them to the ${NAME} tour - a published canvas we host, built to be
|
|
261
|
+
explored: https://tour.marver.design - password \`welcome\`. Tell them it teaches
|
|
262
|
+
selection, devices, themes, variants, and play mode from inside the canvas,
|
|
263
|
+
and that it ends by sending them back to check on you. (Unreachable from this
|
|
264
|
+
machine? Say so and skip it - never stall on it.) Then get to work.
|
|
265
|
+
|
|
266
|
+
NOTE: scaffolders refuse non-empty directories (this repo already holds design/
|
|
267
|
+
and a package.json - the one you likely created with \`npm init -y\` to install
|
|
268
|
+
${NAME} into), so scaffold into a temp dir and merge. The Next.js lane - adapt
|
|
269
|
+
the same shape to whatever stack was agreed:
|
|
194
270
|
|
|
195
271
|
\`\`\`bash
|
|
196
272
|
npx create-next-app@latest app-scaffold --ts --tailwind --app --src-dir --yes
|
|
@@ -200,18 +276,68 @@ npx create-next-app@latest app-scaffold --ts --tailwind --app --src-dir --yes
|
|
|
200
276
|
npx shadcn@latest init
|
|
201
277
|
\`\`\`
|
|
202
278
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
279
|
+
Scaffolder flags drift between versions (create-next-app and shadcn both) - if
|
|
280
|
+
a flag errors or a prompt appears despite --yes, accept the tool's defaults.
|
|
281
|
+
|
|
282
|
+
Known scaffold bug if shadcn was agreed (hit on every create-next-app + shadcn
|
|
283
|
+
run so far): shadcn's
|
|
284
|
+
init rewrites the theme CSS's \`@theme inline\` block and leaves
|
|
285
|
+
\`--font-sans: var(--font-sans)\` - self-referential, resolves to nothing, and
|
|
286
|
+
the app silently renders in the browser's default font. After shadcn init,
|
|
287
|
+
open the theme CSS and bind every font token to a variable that actually
|
|
288
|
+
exists (e.g. \`--font-sans: var(--font-geist-sans)\` under Next); check
|
|
289
|
+
--font-heading and friends for the same circularity.
|
|
290
|
+
|
|
291
|
+
Then START the dev server and
|
|
292
|
+
confirm the starter page renders before moving on. Unsure about the stack's
|
|
293
|
+
conventions? Fetch its docs.
|
|
206
294
|
|
|
207
|
-
##
|
|
295
|
+
## 5. Re-run init
|
|
208
296
|
|
|
209
297
|
\`\`\`bash
|
|
210
298
|
npx ${NAME} init
|
|
211
299
|
\`\`\`
|
|
212
300
|
|
|
213
|
-
init is idempotent: it
|
|
214
|
-
|
|
301
|
+
init is idempotent: it detects the real stack, deletes this file, and
|
|
302
|
+
regenerates AGENTS.md against reality. Verify the wiring (instructions/
|
|
303
|
+
configure.md): frames render styled, one app component imports cleanly.
|
|
304
|
+
DESIGN.md comes next, as part of the first draft.
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
## 6. The first draft - make it impressive, then tour
|
|
308
|
+
|
|
309
|
+
This is the human's first impression of the canvas AND the first draft of their
|
|
310
|
+
product - it sets the direction. Take the time to do it well:
|
|
311
|
+
|
|
312
|
+
- If you can search the web, spend a few minutes understanding the domain from
|
|
313
|
+
step 2's answer; write design/DESIGN.md. The human's look intuition from
|
|
314
|
+
step 2 is the north star - honor it literally. If they said "surprise me",
|
|
315
|
+
commit to a direction and name it in one sentence at the reveal.
|
|
316
|
+
- Build ~4 frames of THEIR product - not lorem, not filler. Hold them to the
|
|
317
|
+
craft bar: instructions/craft.md and instructions/reference/slop.md are
|
|
318
|
+
binding here. Responsive, working in BOTH themes, linked with data-goto so
|
|
319
|
+
play mode flows.
|
|
320
|
+
- UNDERWHELMING IS THE FAILURE MODE. A restrained concept executed thinly
|
|
321
|
+
reads as a wireframe, however careful the type. Every frame needs presence -
|
|
322
|
+
scale, contrast, color, one real visual moment - and the human should feel
|
|
323
|
+
the direction before they read a word. Write the copy like it ships:
|
|
324
|
+
specific, confident, witty where the brand allows, never placeholder. This
|
|
325
|
+
first draft is the product's first impression AND ${NAME}'s - go above and
|
|
326
|
+
beyond.
|
|
327
|
+
- Delete the generic demo scene (design/scenes/demo/) once your frames are in -
|
|
328
|
+
it exists to show YOU the file shapes, not to impress anyone.
|
|
329
|
+
- Create a curated board for them (instructions/boards.md) containing every
|
|
330
|
+
frame the flow visits.
|
|
331
|
+
- Offer a divergence: "want a variant of <frame> exploring a different
|
|
332
|
+
direction?" - one a-/b- pair teaches the variant workflow better than any
|
|
333
|
+
explanation.
|
|
334
|
+
|
|
335
|
+
This first draft skips the written-brief ceremony (the human just told you what
|
|
336
|
+
they are building) but never the quality bar. Then THE REVEAL: start
|
|
337
|
+
\`npx ${NAME} dev\` and give the guided tour from instructions/welcome.md -
|
|
338
|
+
by now the human has played with the hosted tour, so keep it short and let
|
|
339
|
+
their own product carry it. End with the deep link using the PRINTED port -
|
|
340
|
+
\`http://localhost:<port>/#/b/<board>\`, never the bare root URL.
|
|
215
341
|
`;
|
|
216
342
|
/** Next.js frames render OUTSIDE Next - say concretely what that means (friction log #10/#11). */
|
|
217
343
|
const NEXT_NOTES = `- Next.js caveats (frames render in Vite, outside Next):
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@marver-design/marver",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "The agent-native design canvas. A design/ folder, one command, a canvas of live frames built from your repo's real components. The tool ships no AI - your coding agent is the designer.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# Design canvas - agent contract (embedded mode)
|
|
2
2
|
|
|
3
3
|
You design by writing files. The canvas at the printed localhost URL reflects them live.
|
|
4
|
-
Never
|
|
4
|
+
Never drive or automate the canvas UI; read and write files only. (Starting
|
|
5
|
+
`npx marver dev` so the human has a live canvas - first session, or on request -
|
|
6
|
+
is the one allowed touch.)
|
|
5
7
|
|
|
6
8
|
## The method (binding)
|
|
7
9
|
|
|
@@ -10,6 +12,7 @@ file in design/instructions/ - they are short, strict, and part of this contract
|
|
|
10
12
|
|
|
11
13
|
| Phase | When | Read |
|
|
12
14
|
|---|---|---|
|
|
15
|
+
| Welcome | the human's FIRST session, or "what is this?" | instructions/welcome.md |
|
|
13
16
|
| Configure | first session in a repo, or frames render unstyled | instructions/configure.md |
|
|
14
17
|
| Discover | any new surface, feature, or flow | instructions/discover.md |
|
|
15
18
|
| Wireframe | new work: nail structure + copy in throwaway lo-fi | instructions/wireframe.md |
|
|
@@ -22,6 +25,12 @@ Refining an existing screen: Configure must hold, then Build + Review. New work
|
|
|
22
25
|
the full ladder. Unsure which phase you are in? Ask the human - one question beats a
|
|
23
26
|
phase of wrong work.
|
|
24
27
|
|
|
28
|
+
First sessions are teaching sessions: narrate what you do and why in short plain
|
|
29
|
+
sentences - story, not machinery; never read these files aloud to the human
|
|
30
|
+
(voice rules in welcome.md).
|
|
31
|
+
The first-session draft is the ladder's one exception: it skips the written
|
|
32
|
+
brief (the human just said what they are building) but never the craft bar.
|
|
33
|
+
|
|
25
34
|
Stuck, or the human is unhappy with a result? instructions/reference/ holds the deep
|
|
26
35
|
guides (layout, typography, color, motion, copy, states, tuning, critique, concepts) -
|
|
27
36
|
the routing index is at the top of instructions/craft.md. Pull ONE file, apply, return.
|
|
@@ -32,7 +41,8 @@ the routing index is at the top of instructions/craft.md. Pull ONE file, apply,
|
|
|
32
41
|
export const meta = { title: "...", viewport: "mobile" } // literal values only
|
|
33
42
|
// viewport names come from design/config.ts (default: mobile, tablet, laptop, monitor;
|
|
34
43
|
// tv available commented-out). Pick the one the screen is designed for - the human can
|
|
35
|
-
// flip the whole board to any device (Devices menu
|
|
44
|
+
// flip the whole board to any device (Devices menu; digit keys - 0 restores each
|
|
45
|
+
// frame's own size, 1..n per configured device) to check responsiveness.
|
|
36
46
|
- States are sibling frames: empty.tsx, filled.tsx, error.tsx, success.tsx.
|
|
37
47
|
- VERSIONS are sibling frames with letter prefixes, and the canvas understands them:
|
|
38
48
|
design/scenes/landing/a-terminal.tsx + b-editorial.tsx form a VARIANT GROUP - kept
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# Design canvas - agent contract
|
|
2
2
|
|
|
3
3
|
You design by writing files. The canvas at the printed localhost URL reflects them live.
|
|
4
|
-
Never
|
|
4
|
+
Never drive or automate the canvas UI; read and write files only. (Starting
|
|
5
|
+
`npx marver dev` so the human has a live canvas - first session, or on request -
|
|
6
|
+
is the one allowed touch.)
|
|
5
7
|
|
|
6
8
|
## The method (binding)
|
|
7
9
|
|
|
@@ -10,6 +12,7 @@ file in design/instructions/ - they are short, strict, and part of this contract
|
|
|
10
12
|
|
|
11
13
|
| Phase | When | Read |
|
|
12
14
|
|---|---|---|
|
|
15
|
+
| Welcome | the human's FIRST session, or "what is this?" | instructions/welcome.md |
|
|
13
16
|
| Configure | first session in a repo, or frames render unstyled | instructions/configure.md |
|
|
14
17
|
| Discover | any new surface, feature, or flow | instructions/discover.md |
|
|
15
18
|
| Wireframe | new work: nail structure + copy in throwaway lo-fi | instructions/wireframe.md |
|
|
@@ -22,6 +25,12 @@ Refining an existing screen: Configure must hold, then Build + Review. New work
|
|
|
22
25
|
the full ladder. Unsure which phase you are in? Ask the human - one question beats a
|
|
23
26
|
phase of wrong work.
|
|
24
27
|
|
|
28
|
+
First sessions are teaching sessions: narrate what you do and why in short plain
|
|
29
|
+
sentences - story, not machinery; never read these files aloud to the human
|
|
30
|
+
(voice rules in welcome.md).
|
|
31
|
+
The first-session draft is the ladder's one exception: it skips the written
|
|
32
|
+
brief (the human just said what they are building) but never the craft bar.
|
|
33
|
+
|
|
25
34
|
Stuck, or the human is unhappy with a result? instructions/reference/ holds the deep
|
|
26
35
|
guides (layout, typography, color, motion, copy, states, tuning, critique, concepts) -
|
|
27
36
|
the routing index is at the top of instructions/craft.md. Pull ONE file, apply, return.
|
|
@@ -32,7 +41,8 @@ the routing index is at the top of instructions/craft.md. Pull ONE file, apply,
|
|
|
32
41
|
export const meta = { title: "...", viewport: "mobile" } // literal values only
|
|
33
42
|
// viewport names come from design/config.ts (default: mobile, tablet, laptop, monitor;
|
|
34
43
|
// tv available commented-out). Pick the one the screen is designed for - the human can
|
|
35
|
-
// flip the whole board to any device (Devices menu
|
|
44
|
+
// flip the whole board to any device (Devices menu; digit keys - 0 restores each
|
|
45
|
+
// frame's own size, 1..n per configured device) to check responsiveness.
|
|
36
46
|
- States are sibling frames: empty.tsx, filled.tsx, error.tsx, success.tsx.
|
|
37
47
|
- VERSIONS are sibling frames with letter prefixes, and the canvas understands them:
|
|
38
48
|
design/scenes/landing/a-terminal.tsx + b-editorial.tsx form a VARIANT GROUP - kept
|
|
@@ -20,9 +20,12 @@ All four true → idle state. Go design.
|
|
|
20
20
|
|
|
21
21
|
## By repo maturity
|
|
22
22
|
|
|
23
|
+
The human's first session layers on top of this: philosophy, their product on the
|
|
24
|
+
canvas, the tour - that flow lives in instructions/welcome.md, run it alongside.
|
|
25
|
+
|
|
23
26
|
- **Brand-new repo (no app)**: `design/instructions/setup.md` exists and is the
|
|
24
|
-
authority -
|
|
25
|
-
a repo that has nothing to build from.
|
|
27
|
+
authority - follow it (set up the stack WITH the human, re-run init). Do not
|
|
28
|
+
design against a repo that has nothing to build from.
|
|
26
29
|
- **Fresh repo (app scaffolded, little product code)**: init's detection is usually
|
|
27
30
|
right. Verify the checklist, create DESIGN.md from the starter tokens (Path A -
|
|
28
31
|
even a default shadcn theme is a documentable brand), and note in it which parts
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Run this phase for any NEW surface, feature, or project. Skip it only when a brief
|
|
4
4
|
already answers everything below. Its output is a written brief; nothing gets designed
|
|
5
|
-
until the brief has a human nod.
|
|
5
|
+
until the brief has a human nod. (One exception: the first-session draft
|
|
6
|
+
(welcome.md) skips the brief - the human just said what they are building.)
|
|
6
7
|
|
|
7
8
|
## 1. Read the repo, then interview
|
|
8
9
|
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Welcome - the human's first session
|
|
2
|
+
|
|
3
|
+
Run this the FIRST time you work with the human in a repo, or whenever they ask
|
|
4
|
+
what marver is or how it works. Unsure whether they were already welcomed? If
|
|
5
|
+
design/DESIGN.md is missing or no curated board exists yet, treat it as not
|
|
6
|
+
yet. The job: by the end of the session the human understands the tool, has
|
|
7
|
+
seen their own product on the canvas, and knows what to do next. Narrate as you
|
|
8
|
+
go - one short plain sentence per step, teaching by doing, never a lecture.
|
|
9
|
+
|
|
10
|
+
## Voice - tell the story, not the machinery
|
|
11
|
+
|
|
12
|
+
These instruction files are stage directions, not a script to read aloud. Never
|
|
13
|
+
narrate them to the human ("setup.md says...", "step 2 requires...", "per the
|
|
14
|
+
generated instructions I must...") - speak as a designer who is excited to
|
|
15
|
+
start: what we're doing, why it matters, what comes next. Intent over
|
|
16
|
+
internals; one warm, concrete sentence beats three procedural ones.
|
|
17
|
+
|
|
18
|
+
- Robotic: "Init flagged that there's no app yet and pointed me to setup.md.
|
|
19
|
+
I'm following that file now, and step one is a conversation with you."
|
|
20
|
+
- Human: "Canvas is in. Before anything gets built I want to know what we're
|
|
21
|
+
making - that decides everything else."
|
|
22
|
+
|
|
23
|
+
Precision still matters - engineers are reading - but the file paths, step
|
|
24
|
+
numbers, and phase names are yours, not theirs.
|
|
25
|
+
|
|
26
|
+
When you ask the human to choose (the stack, a variant direction), use your
|
|
27
|
+
harness's structured question tool (AskUserQuestion or similar) if one exists -
|
|
28
|
+
short option labels, one-line trade-offs, and a small ASCII sketch per option
|
|
29
|
+
when the choice is visual. Plain prose is the fallback, never the preference.
|
|
30
|
+
Asking through the tool IS the stop: no further tool calls after it, wait for
|
|
31
|
+
the answer.
|
|
32
|
+
|
|
33
|
+
## The pitch (say it early, in your own words)
|
|
34
|
+
|
|
35
|
+
marver co-designs the user experience with the human in real code. Frames are
|
|
36
|
+
not mockups - they are components using the app's actual theme and component
|
|
37
|
+
library. The theme, components, and screens shaped while designing ARE the
|
|
38
|
+
app's building blocks: by the time the design is agreed, most of the UI work
|
|
39
|
+
already exists, and building the product means plugging functionality into it.
|
|
40
|
+
The goal is full alignment on look and feel - across light and dark, across
|
|
41
|
+
every device size - before app logic is written.
|
|
42
|
+
|
|
43
|
+
## Empty repo?
|
|
44
|
+
|
|
45
|
+
design/instructions/setup.md is the authority (it exists only while the repo
|
|
46
|
+
has no app). Follow it end to end; it sends you back here for the reveal.
|
|
47
|
+
|
|
48
|
+
## The waiting room - hand them the hosted tour while you build
|
|
49
|
+
|
|
50
|
+
Building well takes real minutes, and the human should spend them inside a
|
|
51
|
+
canvas, not watching a terminal. The moment the plan is agreed (the stack nod,
|
|
52
|
+
or the Path B confirmation below), send them to the marver tour - a published
|
|
53
|
+
canvas made to be explored: https://tour.marver.design - password `welcome`.
|
|
54
|
+
It teaches selection, devices, themes, variants, and play mode from inside the
|
|
55
|
+
frames, and it ends by sending them back to check on your work. Then build
|
|
56
|
+
without narrating into the void; your next message is the reveal.
|
|
57
|
+
|
|
58
|
+
## Existing codebase - first session flow
|
|
59
|
+
|
|
60
|
+
1. **Say what the app is.** Read the repo (entry point, routes, key screens).
|
|
61
|
+
State your understanding of the product in 2-3 sentences, ask "did I get
|
|
62
|
+
that right?" - then STOP: no further tool calls, end your turn, resume when
|
|
63
|
+
the human replies. (Only exception: they explicitly asked for unattended
|
|
64
|
+
execution - assume, mark UNCONFIRMED, surface it first.)
|
|
65
|
+
2. **Confirm the stack aloud - what detection ACTUALLY found.** Read AGENTS.md's
|
|
66
|
+
UI line and design/theme.css and narrate the reality, for example: "Tailwind
|
|
67
|
+
+ shadcn/ui; brand tokens in <file>; design/theme.css imports them." No
|
|
68
|
+
component library? Say that, and what it means (shared pieces get extracted
|
|
69
|
+
to design/components/). Anything wrong gets fixed now, while it is cheap
|
|
70
|
+
(configure.md, old-repo checklist). Once confirmed, hand them the hosted
|
|
71
|
+
tour (the waiting room above) and get to work.
|
|
72
|
+
3. **Put THEIR product on the canvas - impressively.** Recreate 3-4 of the
|
|
73
|
+
app's real screens as frames from its real components, linked with data-goto
|
|
74
|
+
so play mode flows, working in both themes, responsive. This is the human's
|
|
75
|
+
first impression of the canvas: hold it to the craft bar
|
|
76
|
+
(instructions/craft.md, instructions/reference/slop.md). Create a curated
|
|
77
|
+
board for the set. First sessions skip the written-brief ceremony, never the
|
|
78
|
+
quality bar; real work after the tour runs the full method ladder.
|
|
79
|
+
4. **Explain the working model while building:** existing components are reused
|
|
80
|
+
as-is; missing pieces are created as presentational components - fixture
|
|
81
|
+
props, placeholder handlers - and get real wiring at promotion (where they
|
|
82
|
+
live is AGENTS.md's structure ladder). Look and feel converges first;
|
|
83
|
+
production becomes plugging functionality into agreed UI.
|
|
84
|
+
5. **Offer a divergence.** "Want a variant of <frame> exploring a different
|
|
85
|
+
direction?" One a-/b- pair teaches the variant workflow better than any
|
|
86
|
+
explanation.
|
|
87
|
+
6. **Give the tour** (below), ending with the deep link.
|
|
88
|
+
|
|
89
|
+
## The reveal
|
|
90
|
+
|
|
91
|
+
Deliver conversationally when the first draft is ready - a short guided
|
|
92
|
+
message, not a manual. Start `npx marver dev` if it is not already running
|
|
93
|
+
(allowed for this purpose) and ALWAYS hand a deep link to the board you
|
|
94
|
+
prepared, using the port the dev server PRINTED:
|
|
95
|
+
`http://localhost:<port>/#/b/<board>` - never the bare root URL. The link goes
|
|
96
|
+
at the BOTTOM of the message, on its own line: the human reads through, then
|
|
97
|
+
clicks. The human has already played with the hosted tour by now, so keep it
|
|
98
|
+
short - let their own product carry the moment. The highlights, all real
|
|
99
|
+
features:
|
|
100
|
+
|
|
101
|
+
- **Select and preview.** Click frames (shift-click for several). Digit keys
|
|
102
|
+
switch device presets - 1-4 for the configured devices, 0 back to each
|
|
103
|
+
frame's own size - scoped to the selection when one exists, the whole board
|
|
104
|
+
otherwise. `d` cycles light/dark the same way: selected frames, or the
|
|
105
|
+
entire canvas view (frames pinned to a theme in their meta stay put).
|
|
106
|
+
- **Touch it.** Double-click a frame - the purple ring is interact mode: the
|
|
107
|
+
frame is live, clickable, scrollable.
|
|
108
|
+
- **Play it.** `p` opens play mode: the design full screen in a device, with
|
|
109
|
+
data-goto links navigating between frames like the real app. `[` and `]`
|
|
110
|
+
switch variants in place; devices switch inside play too, including
|
|
111
|
+
full-screen fill.
|
|
112
|
+
- **Explore alternatives.** Letter-prefixed sibling files (a-bold.tsx,
|
|
113
|
+
b-minimal.tsx) form a variant group - badged, kept contiguous, compared at a
|
|
114
|
+
glance. The cheap way to diverge on a direction before committing.
|
|
115
|
+
- **Compose.** `t` re-tidies; boards carry a `layout` recipe for deliberate
|
|
116
|
+
arrangement (instructions/boards.md).
|
|
117
|
+
- **Share it.** `marver build` bundles the boards; `marver serve` with
|
|
118
|
+
MARVER_PASSWORD on any Node host (Railway, Fly, a VPS) publishes them as a
|
|
119
|
+
password-gated canvas the human owns - colleagues get the link plus the
|
|
120
|
+
password. Comments on the board are coming soon.
|
|
121
|
+
|
|
122
|
+
Close by asking what they want to design first.
|