@monoes/monodesign 1.2.11 → 1.2.13

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 (48) hide show
  1. package/cli/engine/browser/injected/index.mjs +16 -18
  2. package/cli/engine/cli/main.mjs +3 -3
  3. package/cli/engine/detect-antipatterns-browser.js +67 -47
  4. package/cli/engine/engines/regex/detect-text.mjs +6 -6
  5. package/cli/engine/engines/static-html/css-cascade.mjs +6 -5
  6. package/cli/engine/engines/static-html/detect-html.mjs +6 -6
  7. package/cli/engine/fix/index.mjs +3 -3
  8. package/cli/engine/node/file-system.mjs +1 -1
  9. package/cli/engine/registry/antipatterns.mjs +1 -1
  10. package/cli/engine/rules/checks.mjs +24 -25
  11. package/cli/engine/shared/color.mjs +2 -2
  12. package/cli/engine/shared/constants.mjs +1 -1
  13. package/cli/engine/shared/inline-ignores.mjs +2 -2
  14. package/cli/lib/monodesign-config.mjs +5 -5
  15. package/package.json +1 -1
  16. package/skill/scripts/context.mjs +4 -4
  17. package/skill/scripts/critique-storage.mjs +1 -1
  18. package/skill/scripts/detect-csp.mjs +1 -6
  19. package/skill/scripts/hook-admin.mjs +6 -6
  20. package/skill/scripts/hook-before-edit.mjs +4 -4
  21. package/skill/scripts/hook-lib.mjs +20 -11
  22. package/skill/scripts/hook.mjs +1 -1
  23. package/skill/scripts/lib/design-parser.mjs +9 -42
  24. package/skill/scripts/lib/is-generated.mjs +1 -1
  25. package/skill/scripts/lib/monodesign-paths.mjs +1 -1
  26. package/skill/scripts/live/event-validation.mjs +13 -13
  27. package/skill/scripts/live/manual-apply.mjs +4 -4
  28. package/skill/scripts/live/manual-edits-buffer.mjs +1 -1
  29. package/skill/scripts/live/session-store.mjs +5 -5
  30. package/skill/scripts/live/svelte-component.mjs +13 -13
  31. package/skill/scripts/live/sveltekit-adapter.mjs +4 -4
  32. package/skill/scripts/live/ui-core.mjs +1 -1
  33. package/skill/scripts/live-accept.mjs +24 -24
  34. package/skill/scripts/live-browser-dom.js +8 -7
  35. package/skill/scripts/live-browser-session.js +8 -7
  36. package/skill/scripts/live-browser.js +405 -432
  37. package/skill/scripts/live-commit-manual-edits.mjs +6 -6
  38. package/skill/scripts/live-copy-edit-agent.mjs +2 -2
  39. package/skill/scripts/live-discard-manual-edits.mjs +1 -1
  40. package/skill/scripts/live-inject.mjs +7 -7
  41. package/skill/scripts/live-insert.mjs +11 -11
  42. package/skill/scripts/live-manual-edit-evidence.mjs +4 -4
  43. package/skill/scripts/live-poll.mjs +5 -5
  44. package/skill/scripts/live-server.mjs +10 -10
  45. package/skill/scripts/live-wrap.mjs +31 -41
  46. package/skill/scripts/live.mjs +5 -5
  47. package/skill/scripts/palette.mjs +3 -1
  48. 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: 'Session markers not found for id: ' + id }));
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 = 'REQUIRED before next poll: carbonize cleanup in ' + result.file + '. See reference/live.md "Required after accept".';
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 = 'REQUIRED before next poll: carbonize cleanup in ' + relFile + '. See reference/live.md "Required after accept".';
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 + ' monodesign-carbonize-start ' + id + ' ' + commentSyntax.close);
297
- lines.push(bodyIndent + '<style data-monodesign-css="' + id + '">' + (isJsx ? '{`' : ''));
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 + ' monodesign-param-values ' + id + ': ' + JSON.stringify(paramValues) + ' ' + commentSyntax.close,
304
+ `${bodyIndent + commentSyntax.open} monodesign-param-values ${id}: ${JSON.stringify(paramValues)} ${commentSyntax.close}`,
305
305
  );
306
306
  }
307
- lines.push(bodyIndent + commentSyntax.open + ' monodesign-carbonize-end ' + id + ' ' + commentSyntax.close);
308
- lines.push(bodyIndent + '<div data-monodesign-variant="' + variantNum + '" ' + variantStyleAttr + '>');
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 + '</div>');
310
+ lines.push(`${bodyIndent}</div>`);
311
311
  };
312
312
 
313
313
  if (isJsx) {
314
314
  const wrapperStyle = 'style={{ display: "contents" }}';
315
- lines.push(indent + '<div data-monodesign-carbonize="' + id + '" ' + wrapperStyle + '>');
316
- pushCarbonizeBody(indent + ' ');
317
- lines.push(indent + '</div>');
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: 'Variant ' + variantNum + ' not found' };
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('<[^>]+data-monodesign-variants=(["\'])' + escaped + '\\1[^>]*>');
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('\\s' + escapeRegExp(name) + '\\s*=\\s*(["\'])(.*?)\\1'));
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 = 'monodesign-variants-start ' + id;
423
- const endPattern = 'monodesign-variants-end ' + id;
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('monodesign-variants-end\\s+' + escapeRegExp(id) + '(?:\\s|--|\\*/|$)').test(line);
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('<([A-Za-z][A-Za-z0-9]*)\\b[^>]*' + attrMatch + '[^>]*>');
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('<(?:/)?' + tagName + '\\b[^>]*>', 'g');
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, 'data-monodesign-variant="' + variantNum + '"');
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 = 'data-monodesign-css="' + id + '"';
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 = 'monodesign-variants-start ' + id;
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
- (function (root) {
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?.('[id^="' + prefix + '"]'));
25
+ return el && (el.id?.startsWith(prefix) || el.closest?.(`[id^="${prefix}"]`));
25
26
  }
26
27
 
27
28
  function pickable(el) {
28
- if (!el || el.nodeType !== 1) return false;
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 += '#' + el.id;
39
- else if (el.classList.length) s += '.' + [...el.classList].slice(0, 2).join('.');
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 || !el.getBoundingClientRect) return null;
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('#' + cssId(id));
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
- (function (root) {
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 || function () { return Math.random().toString(16).slice(2, 10); };
15
- const sessionKey = prefix + '-session';
16
- const handledKey = sessionKey + '-handled';
17
- const scrollKey = sessionKey + '-scroll';
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 || !session.id) return;
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() {