@monoes/monodesign 1.2.11 → 1.2.12
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/cli/engine/browser/injected/index.mjs +16 -18
- package/cli/engine/cli/main.mjs +3 -3
- package/cli/engine/detect-antipatterns-browser.js +67 -47
- package/cli/engine/engines/regex/detect-text.mjs +6 -6
- package/cli/engine/engines/static-html/css-cascade.mjs +6 -5
- package/cli/engine/engines/static-html/detect-html.mjs +6 -6
- package/cli/engine/fix/index.mjs +3 -3
- package/cli/engine/node/file-system.mjs +1 -1
- package/cli/engine/registry/antipatterns.mjs +1 -1
- package/cli/engine/rules/checks.mjs +24 -25
- package/cli/engine/shared/color.mjs +2 -2
- package/cli/engine/shared/constants.mjs +1 -1
- package/cli/engine/shared/inline-ignores.mjs +2 -2
- package/cli/lib/monodesign-config.mjs +5 -5
- package/package.json +11 -10
- package/skill/scripts/context.mjs +4 -4
- package/skill/scripts/critique-storage.mjs +1 -1
- package/skill/scripts/detect-csp.mjs +1 -6
- package/skill/scripts/hook-admin.mjs +6 -6
- package/skill/scripts/hook-before-edit.mjs +4 -4
- package/skill/scripts/hook-lib.mjs +20 -11
- package/skill/scripts/hook.mjs +1 -1
- package/skill/scripts/lib/design-parser.mjs +9 -42
- package/skill/scripts/lib/is-generated.mjs +1 -1
- package/skill/scripts/lib/monodesign-paths.mjs +1 -1
- package/skill/scripts/live/event-validation.mjs +13 -13
- package/skill/scripts/live/manual-apply.mjs +4 -4
- package/skill/scripts/live/manual-edits-buffer.mjs +1 -1
- package/skill/scripts/live/session-store.mjs +5 -5
- package/skill/scripts/live/svelte-component.mjs +13 -13
- package/skill/scripts/live/sveltekit-adapter.mjs +4 -4
- package/skill/scripts/live/ui-core.mjs +1 -1
- package/skill/scripts/live-accept.mjs +24 -24
- package/skill/scripts/live-browser-dom.js +8 -7
- package/skill/scripts/live-browser-session.js +8 -7
- package/skill/scripts/live-browser.js +405 -432
- package/skill/scripts/live-commit-manual-edits.mjs +6 -6
- package/skill/scripts/live-copy-edit-agent.mjs +2 -2
- package/skill/scripts/live-discard-manual-edits.mjs +1 -1
- package/skill/scripts/live-inject.mjs +7 -7
- package/skill/scripts/live-insert.mjs +11 -11
- package/skill/scripts/live-manual-edit-evidence.mjs +4 -4
- package/skill/scripts/live-poll.mjs +5 -5
- package/skill/scripts/live-server.mjs +10 -10
- package/skill/scripts/live-wrap.mjs +31 -41
- package/skill/scripts/live.mjs +5 -5
- package/skill/scripts/palette.mjs +3 -1
- package/skill/scripts/pin.mjs +1 -1
|
@@ -76,7 +76,7 @@ Output (JSON):
|
|
|
76
76
|
const svelteComponentManifest = found ? null : findSvelteComponentManifest(id, process.cwd());
|
|
77
77
|
|
|
78
78
|
if (!found && !svelteComponentManifest) {
|
|
79
|
-
console.log(JSON.stringify({ handled: false, error:
|
|
79
|
+
console.log(JSON.stringify({ handled: false, error: `Session markers not found for id: ${id}` }));
|
|
80
80
|
process.exit(0);
|
|
81
81
|
}
|
|
82
82
|
|
|
@@ -112,7 +112,7 @@ Output (JSON):
|
|
|
112
112
|
};
|
|
113
113
|
}
|
|
114
114
|
if (result.carbonize) {
|
|
115
|
-
result.todo =
|
|
115
|
+
result.todo = `REQUIRED before next poll: carbonize cleanup in ${result.file}. See reference/live.md "Required after accept".`;
|
|
116
116
|
}
|
|
117
117
|
console.log(JSON.stringify({ handled: result.handled !== false, ...result }));
|
|
118
118
|
return;
|
|
@@ -155,7 +155,7 @@ Output (JSON):
|
|
|
155
155
|
// five-step checklist lives in reference/live.md (loaded once per
|
|
156
156
|
// session); repeating it per-event would waste tokens.
|
|
157
157
|
if (result.carbonize) {
|
|
158
|
-
result.todo =
|
|
158
|
+
result.todo = `REQUIRED before next poll: carbonize cleanup in ${relFile}. See reference/live.md "Required after accept".`;
|
|
159
159
|
}
|
|
160
160
|
// Scrub stash entries whose text appeared inside the just-replaced
|
|
161
161
|
// original wrap block. The accept embodies those manual edits (wrap was
|
|
@@ -292,29 +292,29 @@ function buildCarbonizeReplacement({
|
|
|
292
292
|
: 'style="display: contents"';
|
|
293
293
|
|
|
294
294
|
const pushCarbonizeBody = (bodyIndent) => {
|
|
295
|
-
const bodyRestored = reindentContent(restored, indent, bodyIndent
|
|
296
|
-
lines.push(bodyIndent + commentSyntax.open
|
|
297
|
-
lines.push(bodyIndent
|
|
295
|
+
const bodyRestored = reindentContent(restored, indent, `${bodyIndent} `);
|
|
296
|
+
lines.push(`${bodyIndent + commentSyntax.open} monodesign-carbonize-start ${id} ${commentSyntax.close}`);
|
|
297
|
+
lines.push(`${bodyIndent}<style data-monodesign-css="${id}">${isJsx ? '{`' : ''}`);
|
|
298
298
|
for (const cssLine of cssContent) {
|
|
299
299
|
lines.push(bodyIndent + cssLine.trimStart());
|
|
300
300
|
}
|
|
301
301
|
lines.push(bodyIndent + (isJsx ? '`}</style>' : '</style>'));
|
|
302
302
|
if (paramValues && Object.keys(paramValues).length > 0) {
|
|
303
303
|
lines.push(
|
|
304
|
-
bodyIndent + commentSyntax.open
|
|
304
|
+
`${bodyIndent + commentSyntax.open} monodesign-param-values ${id}: ${JSON.stringify(paramValues)} ${commentSyntax.close}`,
|
|
305
305
|
);
|
|
306
306
|
}
|
|
307
|
-
lines.push(bodyIndent + commentSyntax.open
|
|
308
|
-
lines.push(bodyIndent
|
|
307
|
+
lines.push(`${bodyIndent + commentSyntax.open} monodesign-carbonize-end ${id} ${commentSyntax.close}`);
|
|
308
|
+
lines.push(`${bodyIndent}<div data-monodesign-variant="${variantNum}" ${variantStyleAttr}>`);
|
|
309
309
|
lines.push(...bodyRestored);
|
|
310
|
-
lines.push(bodyIndent
|
|
310
|
+
lines.push(`${bodyIndent}</div>`);
|
|
311
311
|
};
|
|
312
312
|
|
|
313
313
|
if (isJsx) {
|
|
314
314
|
const wrapperStyle = 'style={{ display: "contents" }}';
|
|
315
|
-
lines.push(indent
|
|
316
|
-
pushCarbonizeBody(indent
|
|
317
|
-
lines.push(indent
|
|
315
|
+
lines.push(`${indent}<div data-monodesign-carbonize="${id}" ${wrapperStyle}>`);
|
|
316
|
+
pushCarbonizeBody(`${indent} `);
|
|
317
|
+
lines.push(`${indent}</div>`);
|
|
318
318
|
} else {
|
|
319
319
|
pushCarbonizeBody(indent);
|
|
320
320
|
}
|
|
@@ -345,7 +345,7 @@ function handleAccept(id, variantNum, lines, targetFile, paramValues) {
|
|
|
345
345
|
|
|
346
346
|
// Extract the chosen variant's inner content
|
|
347
347
|
const variantContent = extractVariant(lines, block, variantNum);
|
|
348
|
-
if (!variantContent) return { handled: false, error:
|
|
348
|
+
if (!variantContent) return { handled: false, error: `Variant ${variantNum} not found` };
|
|
349
349
|
const originalContent = extractOriginal(lines, block);
|
|
350
350
|
|
|
351
351
|
// Extract CSS block if present
|
|
@@ -382,7 +382,7 @@ function handleAccept(id, variantNum, lines, targetFile, paramValues) {
|
|
|
382
382
|
|
|
383
383
|
function readSourceShadowPreviewMeta(content, id) {
|
|
384
384
|
const escaped = escapeRegExp(id);
|
|
385
|
-
const wrapperRe = new RegExp(
|
|
385
|
+
const wrapperRe = new RegExp(`<[^>]+data-monodesign-variants=(["'])${escaped}\\1[^>]*>`);
|
|
386
386
|
const match = String(content || '').match(wrapperRe);
|
|
387
387
|
if (!match) return null;
|
|
388
388
|
const tag = match[0];
|
|
@@ -395,7 +395,7 @@ function readSourceShadowPreviewMeta(content, id) {
|
|
|
395
395
|
}
|
|
396
396
|
|
|
397
397
|
function readHtmlAttr(tag, name) {
|
|
398
|
-
const match = String(tag || '').match(new RegExp(
|
|
398
|
+
const match = String(tag || '').match(new RegExp(`\\s${escapeRegExp(name)}\\s*=\\s*(["'])(.*?)\\1`));
|
|
399
399
|
if (!match) return null;
|
|
400
400
|
return decodeHtmlAttr(match[2]);
|
|
401
401
|
}
|
|
@@ -419,8 +419,8 @@ function decodeHtmlAttr(value) {
|
|
|
419
419
|
function findMarkerBlock(id, lines) {
|
|
420
420
|
let start = -1;
|
|
421
421
|
let end = -1;
|
|
422
|
-
const startPattern =
|
|
423
|
-
const endPattern =
|
|
422
|
+
const startPattern = `monodesign-variants-start ${id}`;
|
|
423
|
+
const endPattern = `monodesign-variants-end ${id}`;
|
|
424
424
|
|
|
425
425
|
for (let i = 0; i < lines.length; i++) {
|
|
426
426
|
if (start === -1 && lines[i].includes(startPattern)) start = i;
|
|
@@ -504,7 +504,7 @@ function escapeRegExp(value) {
|
|
|
504
504
|
}
|
|
505
505
|
|
|
506
506
|
function isVariantEndMarkerLine(line, id) {
|
|
507
|
-
return new RegExp(
|
|
507
|
+
return new RegExp(`monodesign-variants-end\\s+${escapeRegExp(id)}(?:\\s|--|\\*/|$)`).test(line);
|
|
508
508
|
}
|
|
509
509
|
|
|
510
510
|
function hasVariantWrapperAttr(line, id) {
|
|
@@ -562,7 +562,7 @@ function stripStyleAndJoin(lines, block) {
|
|
|
562
562
|
* Returns the inner string (may be empty), or null if not found.
|
|
563
563
|
*/
|
|
564
564
|
function extractInnerByAttr(text, attrMatch) {
|
|
565
|
-
const openerRe = new RegExp(
|
|
565
|
+
const openerRe = new RegExp(`<([A-Za-z][A-Za-z0-9]*)\\b[^>]*${attrMatch}[^>]*>`);
|
|
566
566
|
const openMatch = text.match(openerRe);
|
|
567
567
|
if (!openMatch) return null;
|
|
568
568
|
|
|
@@ -571,7 +571,7 @@ function extractInnerByAttr(text, attrMatch) {
|
|
|
571
571
|
|
|
572
572
|
// Match any opener or closer of this tag name after innerStart.
|
|
573
573
|
// (Does not match self-closing <TAG … />, which doesn't contribute to depth.)
|
|
574
|
-
const tagRe = new RegExp(
|
|
574
|
+
const tagRe = new RegExp(`<(?:/)?${tagName}\\b[^>]*>`, 'g');
|
|
575
575
|
tagRe.lastIndex = innerStart;
|
|
576
576
|
|
|
577
577
|
let depth = 1;
|
|
@@ -606,7 +606,7 @@ function extractOriginal(lines, block) {
|
|
|
606
606
|
*/
|
|
607
607
|
function extractVariant(lines, block, variantNum) {
|
|
608
608
|
const text = stripStyleAndJoin(lines, block);
|
|
609
|
-
const inner = extractInnerByAttr(text,
|
|
609
|
+
const inner = extractInnerByAttr(text, `data-monodesign-variant="${variantNum}"`);
|
|
610
610
|
if (inner === null) return null;
|
|
611
611
|
const result = inner.split('\n');
|
|
612
612
|
// Collapse a lone empty leading/trailing line (common after string splice).
|
|
@@ -626,7 +626,7 @@ function extractVariant(lines, block, variantNum) {
|
|
|
626
626
|
* the lines between them.
|
|
627
627
|
*/
|
|
628
628
|
function extractCss(lines, block, id) {
|
|
629
|
-
const styleAttr =
|
|
629
|
+
const styleAttr = `data-monodesign-css="${id}"`;
|
|
630
630
|
let inStyle = false;
|
|
631
631
|
const content = [];
|
|
632
632
|
|
|
@@ -747,7 +747,7 @@ function detectCommentSyntax(filePath) {
|
|
|
747
747
|
// ---------------------------------------------------------------------------
|
|
748
748
|
|
|
749
749
|
function findSessionFile(id, cwd) {
|
|
750
|
-
const marker =
|
|
750
|
+
const marker = `monodesign-variants-start ${id}`;
|
|
751
751
|
const searchDirs = ['src', 'app', 'pages', 'components', 'public', 'views', 'templates', '.'];
|
|
752
752
|
const seen = new Set();
|
|
753
753
|
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* chrome mounting, lookup, focus, and picker helpers without depending on the
|
|
6
6
|
* full overlay UI bundle.
|
|
7
7
|
*/
|
|
8
|
-
(
|
|
8
|
+
((root) => {
|
|
9
|
+
// biome-ignore lint/suspicious/noRedundantUseStrict: served to the page as a classic <script> (not an ES module despite package type=module), so this directive is what enables strict mode
|
|
9
10
|
'use strict';
|
|
10
11
|
if (!root) return;
|
|
11
12
|
|
|
@@ -21,11 +22,11 @@
|
|
|
21
22
|
const tagsToSkip = skipTags || new Set();
|
|
22
23
|
|
|
23
24
|
function own(el) {
|
|
24
|
-
return el && (el.id?.startsWith(prefix) || el.closest?.(
|
|
25
|
+
return el && (el.id?.startsWith(prefix) || el.closest?.(`[id^="${prefix}"]`));
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
function pickable(el) {
|
|
28
|
-
if (
|
|
29
|
+
if (el?.nodeType !== 1) return false;
|
|
29
30
|
if (tagsToSkip.has(String(el.tagName || '').toLowerCase())) return false;
|
|
30
31
|
if (own(el)) return false;
|
|
31
32
|
const r = el.getBoundingClientRect();
|
|
@@ -35,8 +36,8 @@
|
|
|
35
36
|
function desc(el) {
|
|
36
37
|
if (!el) return '';
|
|
37
38
|
let s = el.tagName.toLowerCase();
|
|
38
|
-
if (el.id) s +=
|
|
39
|
-
else if (el.classList.length) s +=
|
|
39
|
+
if (el.id) s += `#${el.id}`;
|
|
40
|
+
else if (el.classList.length) s += `.${[...el.classList].slice(0, 2).join('.')}`;
|
|
40
41
|
return s;
|
|
41
42
|
}
|
|
42
43
|
|
|
@@ -45,7 +46,7 @@
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
function makeFrozenAnchor(el) {
|
|
48
|
-
if (!el
|
|
49
|
+
if (!el?.getBoundingClientRect) return null;
|
|
49
50
|
const r = el.getBoundingClientRect();
|
|
50
51
|
if (!rectIsUsableAnchor(r)) return null;
|
|
51
52
|
const rect = {
|
|
@@ -99,7 +100,7 @@
|
|
|
99
100
|
if (found) return found;
|
|
100
101
|
}
|
|
101
102
|
if (uiRoot?.querySelector) {
|
|
102
|
-
const found = uiRoot.querySelector(
|
|
103
|
+
const found = uiRoot.querySelector(`#${cssId(id)}`);
|
|
103
104
|
if (found) return found;
|
|
104
105
|
}
|
|
105
106
|
return doc.getElementById(id);
|
|
@@ -5,16 +5,17 @@
|
|
|
5
5
|
* booting the full overlay UI. Served before live-browser.js and attached to
|
|
6
6
|
* window.__MONODESIGN_LIVE_SESSION__.
|
|
7
7
|
*/
|
|
8
|
-
(
|
|
8
|
+
((root) => {
|
|
9
|
+
// biome-ignore lint/suspicious/noRedundantUseStrict: served to the page as a classic <script> (not an ES module despite package type=module), so this directive is what enables strict mode
|
|
9
10
|
'use strict';
|
|
10
11
|
|
|
11
12
|
function createLiveBrowserSessionState({ prefix, storage, idFactory }) {
|
|
12
13
|
if (!prefix) throw new Error('prefix required');
|
|
13
14
|
const store = storage || root.localStorage;
|
|
14
|
-
const makeId = idFactory ||
|
|
15
|
-
const sessionKey = prefix
|
|
16
|
-
const handledKey = sessionKey
|
|
17
|
-
const scrollKey = sessionKey
|
|
15
|
+
const makeId = idFactory || (() => Math.random().toString(16).slice(2, 10));
|
|
16
|
+
const sessionKey = `${prefix}-session`;
|
|
17
|
+
const handledKey = `${sessionKey}-handled`;
|
|
18
|
+
const scrollKey = `${sessionKey}-scroll`;
|
|
18
19
|
let checkpointRevision = 0;
|
|
19
20
|
const owner = makeId();
|
|
20
21
|
|
|
@@ -43,7 +44,7 @@
|
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
function saveSession(session) {
|
|
46
|
-
if (!session
|
|
47
|
+
if (!session?.id) return;
|
|
47
48
|
const payload = {
|
|
48
49
|
...session,
|
|
49
50
|
checkpointRevision,
|
|
@@ -92,7 +93,7 @@
|
|
|
92
93
|
const raw = safeRead(scrollKey);
|
|
93
94
|
if (raw == null) return null;
|
|
94
95
|
const n = parseFloat(raw);
|
|
95
|
-
return isFinite(n) ? n : null;
|
|
96
|
+
return Number.isFinite(n) ? n : null;
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
function clearScrollY() {
|