@xenonbyte/da-vinci-workflow 0.1.13 → 0.1.15
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/CHANGELOG.md +21 -1
- package/README.md +23 -1
- package/README.zh-CN.md +23 -1
- package/SKILL.md +15 -0
- package/commands/claude/dv/design.md +2 -0
- package/commands/claude/dv/verify.md +2 -0
- package/commands/codex/prompts/dv-design.md +2 -0
- package/commands/codex/prompts/dv-verify.md +1 -0
- package/commands/gemini/dv/design.toml +2 -0
- package/commands/gemini/dv/verify.toml +1 -0
- package/docs/mcp-aware-gate-implementation.md +291 -0
- package/docs/mcp-aware-gate-tests.md +244 -0
- package/docs/mcp-aware-gate.md +246 -0
- package/docs/mode-use-cases.md +2 -0
- package/docs/prompt-presets/README.md +1 -0
- package/docs/prompt-presets/desktop-app.md +4 -0
- package/docs/prompt-presets/mobile-app.md +4 -0
- package/docs/prompt-presets/tablet-app.md +4 -0
- package/docs/prompt-presets/web-app.md +4 -0
- package/docs/visual-adapters.md +9 -0
- package/docs/visual-assist-presets/README.md +4 -2
- package/docs/visual-assist-presets/desktop-app.md +2 -0
- package/docs/visual-assist-presets/mobile-app.md +2 -0
- package/docs/visual-assist-presets/tablet-app.md +2 -0
- package/docs/visual-assist-presets/web-app.md +2 -0
- package/docs/workflow-examples.md +9 -4
- package/docs/zh-CN/mcp-aware-gate-implementation.md +290 -0
- package/docs/zh-CN/mcp-aware-gate-tests.md +244 -0
- package/docs/zh-CN/mcp-aware-gate.md +249 -0
- package/docs/zh-CN/mode-use-cases.md +3 -0
- package/docs/zh-CN/prompt-presets/README.md +1 -0
- package/docs/zh-CN/prompt-presets/desktop-app.md +4 -0
- package/docs/zh-CN/prompt-presets/mobile-app.md +4 -0
- package/docs/zh-CN/prompt-presets/tablet-app.md +4 -0
- package/docs/zh-CN/prompt-presets/web-app.md +4 -0
- package/docs/zh-CN/visual-adapters.md +9 -0
- package/docs/zh-CN/visual-assist-presets/README.md +5 -3
- package/docs/zh-CN/visual-assist-presets/desktop-app.md +2 -0
- package/docs/zh-CN/visual-assist-presets/mobile-app.md +2 -0
- package/docs/zh-CN/visual-assist-presets/tablet-app.md +2 -0
- package/docs/zh-CN/visual-assist-presets/web-app.md +2 -0
- package/docs/zh-CN/workflow-examples.md +9 -4
- package/examples/greenfield-spec-markupflow/DA-VINCI.md +1 -0
- package/examples/greenfield-spec-markupflow/README.md +3 -0
- package/examples/greenfield-spec-markupflow/design-registry.md +3 -0
- package/examples/greenfield-spec-markupflow/pencil-design.md +4 -0
- package/lib/audit.js +348 -0
- package/lib/cli.js +47 -1
- package/lib/mcp-runtime-gate.js +342 -0
- package/package.json +3 -2
- package/references/artifact-templates.md +35 -3
- package/references/checkpoints.md +69 -1
- package/references/design-inputs.md +9 -1
- package/references/layout-hygiene.md +117 -0
- package/references/pencil-design-to-code.md +8 -0
- package/scripts/test-mcp-runtime-gate.js +199 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Layout Hygiene
|
|
2
|
+
|
|
3
|
+
Use this reference when screenshot review or the design checkpoint needs form-factor-specific layout hygiene rules.
|
|
4
|
+
|
|
5
|
+
This layer is separate from `Visual Assist`.
|
|
6
|
+
|
|
7
|
+
- visual adapters decide art direction and composition quality
|
|
8
|
+
- layout hygiene decides whether a screen is structurally healthy enough to expand or implement
|
|
9
|
+
|
|
10
|
+
## Resolution Rule
|
|
11
|
+
|
|
12
|
+
Apply exactly one primary hygiene profile to each reviewed surface:
|
|
13
|
+
|
|
14
|
+
1. mobile
|
|
15
|
+
2. tablet
|
|
16
|
+
3. desktop
|
|
17
|
+
4. web
|
|
18
|
+
|
|
19
|
+
Use the resolved project form factor from `DA-VINCI.md`, `design-brief.md`, or stable codebase signals.
|
|
20
|
+
|
|
21
|
+
For mixed products:
|
|
22
|
+
|
|
23
|
+
- apply the dominant profile per surface
|
|
24
|
+
- record surface-specific exceptions in `design-brief.md` or `pencil-design.md`
|
|
25
|
+
|
|
26
|
+
## Generic Checks
|
|
27
|
+
|
|
28
|
+
Apply these checks to every reviewed surface:
|
|
29
|
+
|
|
30
|
+
- no clipped or edge-colliding primary content
|
|
31
|
+
- no unexplained whitespace bands that break the screen's visual balance
|
|
32
|
+
- a clear dominant working surface or anchor
|
|
33
|
+
- aligned top-chrome rhythm across related screens
|
|
34
|
+
- spacing rhythm that does not bunch one region while leaving another region visually empty
|
|
35
|
+
- screenshot review findings must be interpreted, not treated as an automatic pass
|
|
36
|
+
|
|
37
|
+
## Severity
|
|
38
|
+
|
|
39
|
+
Use these result levels:
|
|
40
|
+
|
|
41
|
+
- `PASS`
|
|
42
|
+
- no blocker-level hygiene failure is present
|
|
43
|
+
- `WARN`
|
|
44
|
+
- minor spacing, rhythm, or proportion issues exist, but the screen is still structurally coherent
|
|
45
|
+
- `BLOCK`
|
|
46
|
+
- any blocker-level hygiene failure exists
|
|
47
|
+
- or screenshot analysis reports hierarchy, spacing, clarity, inconsistency, clipping, or unresolved-placeholder issues and the screen is not revised
|
|
48
|
+
|
|
49
|
+
## Mobile
|
|
50
|
+
|
|
51
|
+
Use for phone-first app screens.
|
|
52
|
+
|
|
53
|
+
Check:
|
|
54
|
+
|
|
55
|
+
- top inset and safe-area rhythm are respected unless the screen is intentionally full-bleed
|
|
56
|
+
- the first content band does not begin flush against the top edge without a clear chrome strategy
|
|
57
|
+
- the main task area is vertically balanced against top chrome and bottom actions
|
|
58
|
+
- bottom trays and action rows do not crowd the main content
|
|
59
|
+
- header and title start lines are consistent across related screens
|
|
60
|
+
|
|
61
|
+
Treat as `BLOCK` when:
|
|
62
|
+
|
|
63
|
+
- top content is visibly pinned to the edge without an intentional full-bleed reason
|
|
64
|
+
- a large unexplained void appears above or within the primary task area
|
|
65
|
+
- a bottom action tray compresses the main task area into an obviously cramped strip
|
|
66
|
+
- related anchor screens use incompatible top-chrome alignment systems
|
|
67
|
+
|
|
68
|
+
## Tablet
|
|
69
|
+
|
|
70
|
+
Use for tablet-first flows or tablet-dominant surfaces.
|
|
71
|
+
|
|
72
|
+
Check:
|
|
73
|
+
|
|
74
|
+
- panes, canvases, and supporting rails use intentional proportions
|
|
75
|
+
- gutters are consistent across primary and secondary regions
|
|
76
|
+
- the screen is not just a stretched phone layout
|
|
77
|
+
- primary and secondary regions have a clear weight relationship
|
|
78
|
+
|
|
79
|
+
Treat as `BLOCK` when:
|
|
80
|
+
|
|
81
|
+
- one side of the screen is heavily compressed while another side is mostly empty without purpose
|
|
82
|
+
- pane ratios feel accidental or unstable
|
|
83
|
+
- the layout is essentially a phone stack widened onto a tablet canvas
|
|
84
|
+
|
|
85
|
+
## Desktop
|
|
86
|
+
|
|
87
|
+
Use for desktop software and dense workspaces.
|
|
88
|
+
|
|
89
|
+
Check:
|
|
90
|
+
|
|
91
|
+
- toolbar, sidebar, workspace, and inspector edges align to a coherent system
|
|
92
|
+
- the main workspace visibly owns the screen
|
|
93
|
+
- panels feel attached to a layout system instead of floating independently
|
|
94
|
+
- chrome height and content start lines are consistent between related screens
|
|
95
|
+
|
|
96
|
+
Treat as `BLOCK` when:
|
|
97
|
+
|
|
98
|
+
- the workspace does not read as the dominant region
|
|
99
|
+
- panels feel like disconnected boxed islands or floating soup
|
|
100
|
+
- top chrome and content starts drift enough to make related screens feel structurally inconsistent
|
|
101
|
+
|
|
102
|
+
## Web
|
|
103
|
+
|
|
104
|
+
Use for browser-based product UI and marketing/product hybrids.
|
|
105
|
+
|
|
106
|
+
Check:
|
|
107
|
+
|
|
108
|
+
- header plus first viewport content fit within a coherent viewport budget
|
|
109
|
+
- max-width and gutters are disciplined
|
|
110
|
+
- responsive behavior does not collapse hierarchy
|
|
111
|
+
- the first impression is not a generic card pile
|
|
112
|
+
|
|
113
|
+
Treat as `BLOCK` when:
|
|
114
|
+
|
|
115
|
+
- header plus hero or workspace visibly overruns the initial viewport without intent
|
|
116
|
+
- gutters or max-width rules drift enough to break hierarchy
|
|
117
|
+
- breakpoint changes turn the screen into a generic stacked-card filler layout
|
|
@@ -10,6 +10,11 @@ Use this priority order:
|
|
|
10
10
|
2. Pencil data for presentation
|
|
11
11
|
3. screenshots only as a visual check
|
|
12
12
|
|
|
13
|
+
Exported screenshots are review artifacts only.
|
|
14
|
+
|
|
15
|
+
- store them under `.da-vinci/changes/<change-id>/exports/`
|
|
16
|
+
- do not treat them as the persisted design source
|
|
17
|
+
|
|
13
18
|
Do not infer behavior from appearance alone.
|
|
14
19
|
|
|
15
20
|
## Read From Pencil
|
|
@@ -33,6 +38,7 @@ If the current active Pencil editor does not match the preferred path in `design
|
|
|
33
38
|
- do not silently continue from the unrelated editor
|
|
34
39
|
- switch to the registered file when possible
|
|
35
40
|
- otherwise reconstruct the registered project-local `.pen` file from MCP-readable document data before implementation depends on it
|
|
41
|
+
- if the editor is still `new` or another unnamed live document, do not describe the project-local `.pen` source as saved yet
|
|
36
42
|
|
|
37
43
|
## Visual Adapter Use
|
|
38
44
|
|
|
@@ -58,8 +64,10 @@ When generating or editing Pencil data:
|
|
|
58
64
|
- use only Pencil-supported properties and layout concepts
|
|
59
65
|
- do not emit web- or CSS-only properties such as `flex` or `margin`
|
|
60
66
|
- prefer smaller, schema-safe batches on anchor screens so errors do not roll back large composition chunks
|
|
67
|
+
- if unsupported-property rollbacks repeat on the same anchor surface, stop treating that pass as stable forward progress until the schema usage is corrected
|
|
61
68
|
- verify the registered project-local `.pen` path becomes shell-visible immediately after the first successful Pencil write
|
|
62
69
|
- keep workflow markdown out of `.da-vinci/designs/`; reserve that directory for `.pen` files only
|
|
70
|
+
- keep screenshot exports out of `.da-vinci/designs/`; write them under `.da-vinci/changes/<change-id>/exports/`
|
|
63
71
|
- after the first approved anchor surfaces, extract a shared primitive family before broad page expansion
|
|
64
72
|
|
|
65
73
|
## Map Pencil To Frontend
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
const assert = require("assert/strict");
|
|
2
|
+
const {
|
|
3
|
+
PASS,
|
|
4
|
+
WARN,
|
|
5
|
+
BLOCK,
|
|
6
|
+
SKIP,
|
|
7
|
+
evaluateMcpRuntimeGate,
|
|
8
|
+
formatMcpRuntimeGateSection
|
|
9
|
+
} = require("../lib/mcp-runtime-gate");
|
|
10
|
+
|
|
11
|
+
function runTest(name, fn) {
|
|
12
|
+
try {
|
|
13
|
+
fn();
|
|
14
|
+
console.log(`PASS ${name}`);
|
|
15
|
+
} catch (error) {
|
|
16
|
+
console.error(`FAIL ${name}`);
|
|
17
|
+
throw error;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
runTest("healthy completion passes", () => {
|
|
22
|
+
const result = evaluateMcpRuntimeGate({
|
|
23
|
+
phase: "completion",
|
|
24
|
+
mcpAvailable: true,
|
|
25
|
+
projectRoot: "/repo",
|
|
26
|
+
activeEditor: "/repo/.da-vinci/designs/cipher-redesign.pen",
|
|
27
|
+
registeredPenPath: ".da-vinci/designs/cipher-redesign.pen",
|
|
28
|
+
shellVisiblePenPath: ".da-vinci/designs/cipher-redesign.pen",
|
|
29
|
+
shellVisiblePenExists: true,
|
|
30
|
+
claimedAnchorIds: ["GfwiK", "mCZ1G", "V8zfE"],
|
|
31
|
+
claimedReviewedScreenIds: ["GfwiK", "mCZ1G", "V8zfE"],
|
|
32
|
+
reviewTargets: ["GfwiK", "mCZ1G", "V8zfE"],
|
|
33
|
+
liveScreens: [
|
|
34
|
+
{ id: "GfwiK", name: "Splash" },
|
|
35
|
+
{ id: "mCZ1G", name: "Home" },
|
|
36
|
+
{ id: "V8zfE", name: "SafeBox" }
|
|
37
|
+
]
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
assert.equal(result.sourceConvergence.status, PASS);
|
|
41
|
+
assert.equal(result.screenPresence.status, PASS);
|
|
42
|
+
assert.equal(result.reviewExecution.status, PASS);
|
|
43
|
+
assert.equal(result.finalStatus, PASS);
|
|
44
|
+
|
|
45
|
+
const section = formatMcpRuntimeGateSection({}, result, { timestamp: "2026-03-27T00:00:00.000Z" });
|
|
46
|
+
assert.match(section, /Final runtime gate status: PASS/);
|
|
47
|
+
assert.match(section, /Source convergence: PASS/);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
runTest("unnamed editor blocks runtime gate", () => {
|
|
51
|
+
const result = evaluateMcpRuntimeGate({
|
|
52
|
+
phase: "completion",
|
|
53
|
+
mcpAvailable: true,
|
|
54
|
+
activeEditor: "new",
|
|
55
|
+
registeredPenPath: ".da-vinci/designs/cipher-redesign.pen",
|
|
56
|
+
shellVisiblePenPath: ".da-vinci/designs/cipher-redesign.pen",
|
|
57
|
+
shellVisiblePenExists: true,
|
|
58
|
+
claimedAnchorIds: ["GfwiK"],
|
|
59
|
+
claimedReviewedScreenIds: ["GfwiK"],
|
|
60
|
+
reviewTargets: ["GfwiK"],
|
|
61
|
+
liveScreens: [{ id: "GfwiK", name: "Splash" }]
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
assert.equal(result.sourceConvergence.status, BLOCK);
|
|
65
|
+
assert.equal(result.finalStatus, BLOCK);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
runTest("live screens without shell-visible pen block source convergence", () => {
|
|
69
|
+
const result = evaluateMcpRuntimeGate({
|
|
70
|
+
phase: "completion",
|
|
71
|
+
mcpAvailable: true,
|
|
72
|
+
projectRoot: "/repo",
|
|
73
|
+
activeEditor: "/repo/.da-vinci/designs/cipher-redesign.pen",
|
|
74
|
+
registeredPenPath: ".da-vinci/designs/cipher-redesign.pen",
|
|
75
|
+
shellVisiblePenPath: ".da-vinci/designs/cipher-redesign.pen",
|
|
76
|
+
shellVisiblePenExists: false,
|
|
77
|
+
claimedAnchorIds: ["GfwiK"],
|
|
78
|
+
claimedReviewedScreenIds: ["GfwiK"],
|
|
79
|
+
reviewTargets: ["GfwiK"],
|
|
80
|
+
liveScreens: [{ id: "GfwiK", name: "Splash" }]
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
assert.equal(result.sourceConvergence.status, BLOCK);
|
|
84
|
+
assert.equal(result.finalStatus, BLOCK);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
runTest("missing claimed anchor blocks screen presence", () => {
|
|
88
|
+
const result = evaluateMcpRuntimeGate({
|
|
89
|
+
phase: "completion",
|
|
90
|
+
mcpAvailable: true,
|
|
91
|
+
projectRoot: "/repo",
|
|
92
|
+
activeEditor: "/repo/.da-vinci/designs/cipher-redesign.pen",
|
|
93
|
+
registeredPenPath: ".da-vinci/designs/cipher-redesign.pen",
|
|
94
|
+
shellVisiblePenPath: ".da-vinci/designs/cipher-redesign.pen",
|
|
95
|
+
shellVisiblePenExists: true,
|
|
96
|
+
claimedAnchorIds: ["GfwiK", "mCZ1G"],
|
|
97
|
+
claimedReviewedScreenIds: ["GfwiK"],
|
|
98
|
+
reviewTargets: ["GfwiK"],
|
|
99
|
+
liveScreens: [{ id: "GfwiK", name: "Splash" }]
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
assert.equal(result.screenPresence.status, BLOCK);
|
|
103
|
+
assert.equal(result.finalStatus, BLOCK);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
runTest("ignored review blockers block review execution", () => {
|
|
107
|
+
const result = evaluateMcpRuntimeGate({
|
|
108
|
+
phase: "completion",
|
|
109
|
+
mcpAvailable: true,
|
|
110
|
+
projectRoot: "/repo",
|
|
111
|
+
activeEditor: "/repo/.da-vinci/designs/cipher-redesign.pen",
|
|
112
|
+
registeredPenPath: ".da-vinci/designs/cipher-redesign.pen",
|
|
113
|
+
shellVisiblePenPath: ".da-vinci/designs/cipher-redesign.pen",
|
|
114
|
+
shellVisiblePenExists: true,
|
|
115
|
+
claimedAnchorIds: ["GfwiK"],
|
|
116
|
+
claimedReviewedScreenIds: ["GfwiK"],
|
|
117
|
+
reviewTargets: ["GfwiK"],
|
|
118
|
+
liveScreens: [{ id: "GfwiK", name: "Splash" }],
|
|
119
|
+
reviewBlockersIgnored: true
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
assert.equal(result.reviewExecution.status, BLOCK);
|
|
123
|
+
assert.equal(result.finalStatus, BLOCK);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
runTest("mcp unavailable warns instead of passing", () => {
|
|
127
|
+
const result = evaluateMcpRuntimeGate({
|
|
128
|
+
phase: "completion",
|
|
129
|
+
mcpAvailable: false,
|
|
130
|
+
activeEditor: "",
|
|
131
|
+
registeredPenPath: ".da-vinci/designs/cipher-redesign.pen",
|
|
132
|
+
shellVisiblePenPath: ".da-vinci/designs/cipher-redesign.pen",
|
|
133
|
+
shellVisiblePenExists: true
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
assert.equal(result.sourceConvergence.status, WARN);
|
|
137
|
+
assert.equal(result.screenPresence.status, WARN);
|
|
138
|
+
assert.equal(result.reviewExecution.status, WARN);
|
|
139
|
+
assert.equal(result.finalStatus, WARN);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
runTest("first-write phase can skip screen and review checks", () => {
|
|
143
|
+
const result = evaluateMcpRuntimeGate({
|
|
144
|
+
phase: "first_write",
|
|
145
|
+
mcpAvailable: true,
|
|
146
|
+
projectRoot: "/repo",
|
|
147
|
+
activeEditor: "/repo/.da-vinci/designs/cipher-redesign.pen",
|
|
148
|
+
registeredPenPath: ".da-vinci/designs/cipher-redesign.pen",
|
|
149
|
+
shellVisiblePenPath: ".da-vinci/designs/cipher-redesign.pen",
|
|
150
|
+
shellVisiblePenExists: true,
|
|
151
|
+
liveScreens: [{ id: "GfwiK", name: "Splash" }]
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
assert.equal(result.sourceConvergence.status, PASS);
|
|
155
|
+
assert.equal(result.screenPresence.status, SKIP);
|
|
156
|
+
assert.equal(result.reviewExecution.status, SKIP);
|
|
157
|
+
assert.equal(result.finalStatus, PASS);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
runTest("documented reconciliation downgrades mismatch to warn", () => {
|
|
161
|
+
const result = evaluateMcpRuntimeGate({
|
|
162
|
+
phase: "completion",
|
|
163
|
+
mcpAvailable: true,
|
|
164
|
+
projectRoot: "/repo",
|
|
165
|
+
activeEditor: "/tmp/other-live.pen",
|
|
166
|
+
registeredPenPath: ".da-vinci/designs/cipher-redesign.pen",
|
|
167
|
+
shellVisiblePenPath: ".da-vinci/designs/cipher-redesign.pen",
|
|
168
|
+
shellVisiblePenExists: true,
|
|
169
|
+
documentedReconciliation: true,
|
|
170
|
+
claimedAnchorIds: ["GfwiK"],
|
|
171
|
+
claimedReviewedScreenIds: ["GfwiK"],
|
|
172
|
+
reviewTargets: ["GfwiK"],
|
|
173
|
+
liveScreens: [{ id: "GfwiK", name: "Splash" }]
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
assert.equal(result.sourceConvergence.status, WARN);
|
|
177
|
+
assert.equal(result.finalStatus, WARN);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
runTest("same basename but different absolute path blocks without reconciliation", () => {
|
|
181
|
+
const result = evaluateMcpRuntimeGate({
|
|
182
|
+
phase: "completion",
|
|
183
|
+
mcpAvailable: true,
|
|
184
|
+
projectRoot: "/repo",
|
|
185
|
+
activeEditor: "/tmp/cipher-redesign.pen",
|
|
186
|
+
registeredPenPath: ".da-vinci/designs/cipher-redesign.pen",
|
|
187
|
+
shellVisiblePenPath: ".da-vinci/designs/cipher-redesign.pen",
|
|
188
|
+
shellVisiblePenExists: true,
|
|
189
|
+
claimedAnchorIds: ["GfwiK"],
|
|
190
|
+
claimedReviewedScreenIds: ["GfwiK"],
|
|
191
|
+
reviewTargets: ["GfwiK"],
|
|
192
|
+
liveScreens: [{ id: "GfwiK", name: "Splash" }]
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
assert.equal(result.sourceConvergence.status, BLOCK);
|
|
196
|
+
assert.equal(result.finalStatus, BLOCK);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
console.log("All MCP runtime gate tests passed.");
|