@monoes/monomindcli 2.14.1 → 2.15.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 (194) hide show
  1. package/.claude/helpers/control-start.cjs +10 -13
  2. package/.claude/skills/monodesign/scripts/context.mjs +4 -4
  3. package/.claude/skills/monodesign/scripts/critique-storage.mjs +1 -1
  4. package/.claude/skills/monodesign/scripts/detect-csp.mjs +1 -6
  5. package/.claude/skills/monodesign/scripts/detector/browser/injected/index.mjs +16 -18
  6. package/.claude/skills/monodesign/scripts/detector/cli/main.mjs +3 -3
  7. package/.claude/skills/monodesign/scripts/detector/detect-antipatterns-browser.js +67 -47
  8. package/.claude/skills/monodesign/scripts/detector/engines/regex/detect-text.mjs +6 -6
  9. package/.claude/skills/monodesign/scripts/detector/engines/static-html/css-cascade.mjs +6 -5
  10. package/.claude/skills/monodesign/scripts/detector/engines/static-html/detect-html.mjs +6 -6
  11. package/.claude/skills/monodesign/scripts/detector/fix/index.mjs +3 -3
  12. package/.claude/skills/monodesign/scripts/detector/node/file-system.mjs +1 -1
  13. package/.claude/skills/monodesign/scripts/detector/registry/antipatterns.mjs +1 -1
  14. package/.claude/skills/monodesign/scripts/detector/rules/checks.mjs +24 -25
  15. package/.claude/skills/monodesign/scripts/detector/shared/color.mjs +2 -2
  16. package/.claude/skills/monodesign/scripts/detector/shared/constants.mjs +1 -1
  17. package/.claude/skills/monodesign/scripts/detector/shared/inline-ignores.mjs +2 -2
  18. package/.claude/skills/monodesign/scripts/hook-admin.mjs +6 -6
  19. package/.claude/skills/monodesign/scripts/hook-before-edit.mjs +4 -4
  20. package/.claude/skills/monodesign/scripts/hook-lib.mjs +20 -11
  21. package/.claude/skills/monodesign/scripts/hook.mjs +1 -1
  22. package/.claude/skills/monodesign/scripts/lib/design-parser.mjs +9 -42
  23. package/.claude/skills/monodesign/scripts/lib/is-generated.mjs +1 -1
  24. package/.claude/skills/monodesign/scripts/lib/monodesign-config.mjs +5 -5
  25. package/.claude/skills/monodesign/scripts/lib/monodesign-paths.mjs +1 -1
  26. package/.claude/skills/monodesign/scripts/live/event-validation.mjs +13 -13
  27. package/.claude/skills/monodesign/scripts/live/manual-apply.mjs +4 -4
  28. package/.claude/skills/monodesign/scripts/live/manual-edits-buffer.mjs +1 -1
  29. package/.claude/skills/monodesign/scripts/live/session-store.mjs +5 -5
  30. package/.claude/skills/monodesign/scripts/live/svelte-component.mjs +13 -13
  31. package/.claude/skills/monodesign/scripts/live/sveltekit-adapter.mjs +4 -4
  32. package/.claude/skills/monodesign/scripts/live/ui-core.mjs +1 -1
  33. package/.claude/skills/monodesign/scripts/live-accept.mjs +24 -24
  34. package/.claude/skills/monodesign/scripts/live-browser-dom.js +8 -7
  35. package/.claude/skills/monodesign/scripts/live-browser-session.js +8 -7
  36. package/.claude/skills/monodesign/scripts/live-browser.js +405 -432
  37. package/.claude/skills/monodesign/scripts/live-commit-manual-edits.mjs +6 -6
  38. package/.claude/skills/monodesign/scripts/live-copy-edit-agent.mjs +2 -2
  39. package/.claude/skills/monodesign/scripts/live-discard-manual-edits.mjs +1 -1
  40. package/.claude/skills/monodesign/scripts/live-inject.mjs +7 -7
  41. package/.claude/skills/monodesign/scripts/live-insert.mjs +11 -11
  42. package/.claude/skills/monodesign/scripts/live-manual-edit-evidence.mjs +4 -4
  43. package/.claude/skills/monodesign/scripts/live-poll.mjs +5 -5
  44. package/.claude/skills/monodesign/scripts/live-server.mjs +10 -10
  45. package/.claude/skills/monodesign/scripts/live-wrap.mjs +31 -41
  46. package/.claude/skills/monodesign/scripts/live.mjs +5 -5
  47. package/.claude/skills/monodesign/scripts/palette.mjs +3 -1
  48. package/.claude/skills/monodesign/scripts/pin.mjs +1 -1
  49. package/dist/src/commands/doc-filters.d.ts.map +1 -1
  50. package/dist/src/commands/doc-filters.js +6 -0
  51. package/dist/src/commands/doc-filters.js.map +1 -1
  52. package/dist/src/commands/doc-library.d.ts +2 -1
  53. package/dist/src/commands/doc-library.d.ts.map +1 -1
  54. package/dist/src/commands/doc-library.js +66 -2
  55. package/dist/src/commands/doc-library.js.map +1 -1
  56. package/dist/src/commands/doc.d.ts.map +1 -1
  57. package/dist/src/commands/doc.js +2 -0
  58. package/dist/src/commands/doc.js.map +1 -1
  59. package/dist/src/commands/ui.d.ts.map +1 -1
  60. package/dist/src/commands/ui.js +60 -0
  61. package/dist/src/commands/ui.js.map +1 -1
  62. package/dist/src/knowledge/capture-envelope.d.ts +5 -0
  63. package/dist/src/knowledge/capture-envelope.d.ts.map +1 -1
  64. package/dist/src/knowledge/capture-envelope.js +2 -0
  65. package/dist/src/knowledge/capture-envelope.js.map +1 -1
  66. package/dist/src/knowledge/document-chunking.d.ts +42 -0
  67. package/dist/src/knowledge/document-chunking.d.ts.map +1 -0
  68. package/dist/src/knowledge/document-chunking.js +288 -0
  69. package/dist/src/knowledge/document-chunking.js.map +1 -0
  70. package/dist/src/knowledge/document-index.d.ts +124 -0
  71. package/dist/src/knowledge/document-index.d.ts.map +1 -0
  72. package/dist/src/knowledge/document-index.js +314 -0
  73. package/dist/src/knowledge/document-index.js.map +1 -0
  74. package/dist/src/knowledge/document-ingest.d.ts +23 -0
  75. package/dist/src/knowledge/document-ingest.d.ts.map +1 -0
  76. package/dist/src/knowledge/document-ingest.js +368 -0
  77. package/dist/src/knowledge/document-ingest.js.map +1 -0
  78. package/dist/src/knowledge/document-pipeline.d.ts +26 -208
  79. package/dist/src/knowledge/document-pipeline.d.ts.map +1 -1
  80. package/dist/src/knowledge/document-pipeline.js +25 -1104
  81. package/dist/src/knowledge/document-pipeline.js.map +1 -1
  82. package/dist/src/knowledge/document-search.d.ts +27 -0
  83. package/dist/src/knowledge/document-search.d.ts.map +1 -0
  84. package/dist/src/knowledge/document-search.js +138 -0
  85. package/dist/src/knowledge/document-search.js.map +1 -0
  86. package/dist/src/knowledge/document-store.d.ts +28 -0
  87. package/dist/src/knowledge/document-store.d.ts.map +1 -0
  88. package/dist/src/knowledge/document-store.js +61 -0
  89. package/dist/src/knowledge/document-store.js.map +1 -0
  90. package/dist/src/knowledge/document-types.d.ts +103 -0
  91. package/dist/src/knowledge/document-types.d.ts.map +1 -0
  92. package/dist/src/knowledge/document-types.js +12 -0
  93. package/dist/src/knowledge/document-types.js.map +1 -0
  94. package/dist/src/knowledge/highlights.d.ts +168 -0
  95. package/dist/src/knowledge/highlights.d.ts.map +1 -0
  96. package/dist/src/knowledge/highlights.js +311 -0
  97. package/dist/src/knowledge/highlights.js.map +1 -0
  98. package/dist/src/knowledge/lookup.d.ts +80 -0
  99. package/dist/src/knowledge/lookup.d.ts.map +1 -0
  100. package/dist/src/knowledge/lookup.js +156 -0
  101. package/dist/src/knowledge/lookup.js.map +1 -0
  102. package/dist/src/knowledge/okf-bundle.d.ts +19 -0
  103. package/dist/src/knowledge/okf-bundle.d.ts.map +1 -0
  104. package/dist/src/knowledge/okf-bundle.js +106 -0
  105. package/dist/src/knowledge/okf-bundle.js.map +1 -0
  106. package/dist/src/knowledge/profile-store.d.ts +134 -0
  107. package/dist/src/knowledge/profile-store.d.ts.map +1 -0
  108. package/dist/src/knowledge/profile-store.js +237 -0
  109. package/dist/src/knowledge/profile-store.js.map +1 -0
  110. package/dist/src/orgrt/agent-runner.d.ts +4 -0
  111. package/dist/src/orgrt/agent-runner.d.ts.map +1 -1
  112. package/dist/src/orgrt/agent-runner.js +22 -0
  113. package/dist/src/orgrt/agent-runner.js.map +1 -1
  114. package/dist/src/orgrt/antigravity-runner.d.ts.map +1 -1
  115. package/dist/src/orgrt/antigravity-runner.js +2 -1
  116. package/dist/src/orgrt/antigravity-runner.js.map +1 -1
  117. package/dist/src/orgrt/authority-mask.d.ts +32 -0
  118. package/dist/src/orgrt/authority-mask.d.ts.map +1 -0
  119. package/dist/src/orgrt/authority-mask.js +135 -0
  120. package/dist/src/orgrt/authority-mask.js.map +1 -0
  121. package/dist/src/orgrt/codex-runner.d.ts.map +1 -1
  122. package/dist/src/orgrt/codex-runner.js +2 -1
  123. package/dist/src/orgrt/codex-runner.js.map +1 -1
  124. package/dist/src/orgrt/copilot-runner.d.ts.map +1 -1
  125. package/dist/src/orgrt/copilot-runner.js +2 -1
  126. package/dist/src/orgrt/copilot-runner.js.map +1 -1
  127. package/dist/src/orgrt/crush-runner.d.ts.map +1 -1
  128. package/dist/src/orgrt/crush-runner.js +6 -1
  129. package/dist/src/orgrt/crush-runner.js.map +1 -1
  130. package/dist/src/orgrt/daemon.d.ts +4 -0
  131. package/dist/src/orgrt/daemon.d.ts.map +1 -1
  132. package/dist/src/orgrt/daemon.js +13 -2
  133. package/dist/src/orgrt/daemon.js.map +1 -1
  134. package/dist/src/orgrt/decisions.d.ts +9 -0
  135. package/dist/src/orgrt/decisions.d.ts.map +1 -1
  136. package/dist/src/orgrt/decisions.js +32 -5
  137. package/dist/src/orgrt/decisions.js.map +1 -1
  138. package/dist/src/orgrt/file-roots.d.ts +2 -1
  139. package/dist/src/orgrt/file-roots.d.ts.map +1 -1
  140. package/dist/src/orgrt/file-roots.js +7 -3
  141. package/dist/src/orgrt/file-roots.js.map +1 -1
  142. package/dist/src/orgrt/grok-runner.d.ts.map +1 -1
  143. package/dist/src/orgrt/grok-runner.js +2 -1
  144. package/dist/src/orgrt/grok-runner.js.map +1 -1
  145. package/dist/src/orgrt/hermes-runner.d.ts.map +1 -1
  146. package/dist/src/orgrt/hermes-runner.js +2 -1
  147. package/dist/src/orgrt/hermes-runner.js.map +1 -1
  148. package/dist/src/orgrt/inbox.d.ts.map +1 -1
  149. package/dist/src/orgrt/inbox.js +70 -4
  150. package/dist/src/orgrt/inbox.js.map +1 -1
  151. package/dist/src/orgrt/kimicode-runner.d.ts.map +1 -1
  152. package/dist/src/orgrt/kimicode-runner.js +2 -1
  153. package/dist/src/orgrt/kimicode-runner.js.map +1 -1
  154. package/dist/src/orgrt/opencode-runner.d.ts.map +1 -1
  155. package/dist/src/orgrt/opencode-runner.js +3 -2
  156. package/dist/src/orgrt/opencode-runner.js.map +1 -1
  157. package/dist/src/orgrt/pi-rpc-runner.d.ts.map +1 -1
  158. package/dist/src/orgrt/pi-rpc-runner.js +3 -2
  159. package/dist/src/orgrt/pi-rpc-runner.js.map +1 -1
  160. package/dist/src/orgrt/pi-runner.d.ts.map +1 -1
  161. package/dist/src/orgrt/pi-runner.js +2 -1
  162. package/dist/src/orgrt/pi-runner.js.map +1 -1
  163. package/dist/src/orgrt/policy.d.ts.map +1 -1
  164. package/dist/src/orgrt/policy.js +3 -0
  165. package/dist/src/orgrt/policy.js.map +1 -1
  166. package/dist/src/orgrt/qwen-rpc-runner.d.ts.map +1 -1
  167. package/dist/src/orgrt/qwen-rpc-runner.js +3 -2
  168. package/dist/src/orgrt/qwen-rpc-runner.js.map +1 -1
  169. package/dist/src/orgrt/qwen-runner.d.ts.map +1 -1
  170. package/dist/src/orgrt/qwen-runner.js +2 -1
  171. package/dist/src/orgrt/qwen-runner.js.map +1 -1
  172. package/dist/src/orgrt/role-sandbox.d.ts +21 -0
  173. package/dist/src/orgrt/role-sandbox.d.ts.map +1 -1
  174. package/dist/src/orgrt/role-sandbox.js +31 -6
  175. package/dist/src/orgrt/role-sandbox.js.map +1 -1
  176. package/dist/src/orgrt/session.d.ts.map +1 -1
  177. package/dist/src/orgrt/session.js +21 -2
  178. package/dist/src/orgrt/session.js.map +1 -1
  179. package/dist/src/orgrt/task-dag.d.ts +3 -0
  180. package/dist/src/orgrt/task-dag.d.ts.map +1 -1
  181. package/dist/src/orgrt/task-dag.js +1 -0
  182. package/dist/src/orgrt/task-dag.js.map +1 -1
  183. package/dist/src/orgrt/types.d.ts +5 -0
  184. package/dist/src/orgrt/types.d.ts.map +1 -1
  185. package/dist/src/orgrt/types.js +23 -1
  186. package/dist/src/orgrt/types.js.map +1 -1
  187. package/dist/src/ui/dashboard.html +28 -848
  188. package/dist/src/ui/human-auth.mjs +103 -0
  189. package/dist/src/ui/org-hil.mjs +86 -37
  190. package/dist/src/ui/org-runtime.mjs +21 -13
  191. package/dist/src/ui/routes-org.mjs +49 -445
  192. package/dist/src/ui/server.mjs +90 -2
  193. package/dist/tsconfig.tsbuildinfo +1 -1
  194. package/package.json +6 -6
@@ -62,30 +62,30 @@ function validateInsertGenerate(msg) {
62
62
 
63
63
  function validateReplaceGenerate(msg) {
64
64
  if (!msg.action || !VISUAL_ACTIONS.includes(msg.action)) return 'generate: invalid action';
65
- if (!msg.element || !msg.element.outerHTML) return 'generate: missing element context';
65
+ if (!msg.element?.outerHTML) return 'generate: missing element context';
66
66
  return validateAnnotationFields(msg);
67
67
  }
68
68
 
69
69
  function validateManualEditEvent(msg, label) {
70
- if (!isValidId(msg.id)) return label + ': missing or malformed id';
71
- if (!msg.pageUrl || typeof msg.pageUrl !== 'string') return label + ': missing pageUrl';
72
- if (!msg.element || typeof msg.element !== 'object') return label + ': missing element';
73
- if (!Array.isArray(msg.ops) || msg.ops.length === 0) return label + ': ops must be non-empty array';
74
- if (msg.ops.length > 100) return label + ': too many ops (max 100)';
70
+ if (!isValidId(msg.id)) return `${label}: missing or malformed id`;
71
+ if (!msg.pageUrl || typeof msg.pageUrl !== 'string') return `${label}: missing pageUrl`;
72
+ if (!msg.element || typeof msg.element !== 'object') return `${label}: missing element`;
73
+ if (!Array.isArray(msg.ops) || msg.ops.length === 0) return `${label}: ops must be non-empty array`;
74
+ if (msg.ops.length > 100) return `${label}: too many ops (max 100)`;
75
75
  for (const op of msg.ops) {
76
- if (typeof op.ref !== 'string') return label + ': op.ref required';
77
- if (typeof op.tag !== 'string') return label + ': op.tag required';
78
- if (typeof op.originalText !== 'string') return label + ': op.originalText required';
76
+ if (typeof op.ref !== 'string') return `${label}: op.ref required`;
77
+ if (typeof op.tag !== 'string') return `${label}: op.tag required`;
78
+ if (typeof op.originalText !== 'string') return `${label}: op.originalText required`;
79
79
  if (op.deleted !== true && typeof op.newText !== 'string') {
80
- return label + ': text op requires newText';
80
+ return `${label}: text op requires newText`;
81
81
  }
82
82
  if (typeof op.newText === 'string') {
83
83
  if (op.deleted !== true && op.newText.trim().length === 0) {
84
- return label + ': newText cannot be empty';
84
+ return `${label}: newText cannot be empty`;
85
85
  }
86
86
  const forbidden = validateManualEditText(op.newText);
87
87
  if (forbidden) {
88
- return label + ': newText cannot contain ' + forbidden.join(' ') + ' (plain text only; ask the AI to insert markup)';
88
+ return `${label}: newText cannot contain ${forbidden.join(' ')} (plain text only; ask the AI to insert markup)`;
89
89
  }
90
90
  }
91
91
  }
@@ -132,6 +132,6 @@ export function validateEvent(msg) {
132
132
  if (msg.pageUrl !== undefined && typeof msg.pageUrl !== 'string') return 'steer: pageUrl must be string';
133
133
  return null;
134
134
  default:
135
- return 'Unknown event type: ' + msg.type;
135
+ return `Unknown event type: ${msg.type}`;
136
136
  }
137
137
  }
@@ -326,7 +326,7 @@ export function writeManualApplyEvidence(eventId, batch, cwd = process.cwd()) {
326
326
  const dir = manualApplyEvidenceDir(cwd);
327
327
  fs.mkdirSync(dir, { recursive: true });
328
328
  const evidencePath = path.join(dir, `${eventId}.json`);
329
- fs.writeFileSync(evidencePath, JSON.stringify(batch, null, 2) + '\n', 'utf-8');
329
+ fs.writeFileSync(evidencePath, `${JSON.stringify(batch, null, 2)}\n`, 'utf-8');
330
330
  return evidencePath;
331
331
  }
332
332
 
@@ -495,7 +495,7 @@ function invalidManualApplyResult(reason, eventId, extra = {}) {
495
495
  }
496
496
 
497
497
  export function validateManualApplyResultMessage(msg, deferred) {
498
- let data = msg?.data;
498
+ const data = msg?.data;
499
499
  const eventId = msg?.id || deferred?.event?.id || 'EVENT_ID';
500
500
  if (!data || typeof data !== 'object' || Array.isArray(data)) {
501
501
  return invalidManualApplyResult('missing_result_data', eventId);
@@ -743,7 +743,7 @@ export function writeManualApplyTransaction({ cwd = process.cwd(), pageUrl = nul
743
743
  }),
744
744
  };
745
745
  fs.mkdirSync(path.dirname(file), { recursive: true });
746
- fs.writeFileSync(`${file}.tmp`, JSON.stringify(transaction, null, 2) + '\n', 'utf-8');
746
+ fs.writeFileSync(`${file}.tmp`, `${JSON.stringify(transaction, null, 2)}\n`, 'utf-8');
747
747
  fs.renameSync(`${file}.tmp`, file);
748
748
  return transaction;
749
749
  }
@@ -935,5 +935,5 @@ export function compactManualLogText(value, max = 200) {
935
935
  if (typeof value !== 'string') return undefined;
936
936
  const normalized = value.replace(/\s+/g, ' ').trim();
937
937
  if (normalized.length <= max) return normalized;
938
- return normalized.slice(0, max) + `... [truncated ${normalized.length - max} chars]`;
938
+ return `${normalized.slice(0, max)}... [truncated ${normalized.length - max} chars]`;
939
939
  }
@@ -41,7 +41,7 @@ function readBufferInternal(cwd, { strict }) {
41
41
  return { version: BUFFER_VERSION, entries: parsed.entries };
42
42
  } catch (err) {
43
43
  if (strict && err?.code !== 'ENOENT') {
44
- throw new Error('manual_edit_buffer_unreadable: ' + (err.message || String(err)));
44
+ throw new Error(`manual_edit_buffer_unreadable: ${err.message || String(err)}`);
45
45
  }
46
46
  return { version: BUFFER_VERSION, entries: [] };
47
47
  }
@@ -51,7 +51,7 @@ export function createLiveSessionStore({ cwd = process.cwd(), sessionId } = {})
51
51
  ts: new Date().toISOString(),
52
52
  event: normalized,
53
53
  };
54
- fs.appendFileSync(journalPath, JSON.stringify(entry) + '\n');
54
+ fs.appendFileSync(journalPath, `${JSON.stringify(entry)}\n`);
55
55
  const next = applyEvent(prior.snapshot, entry, prior.diagnostics);
56
56
  snapshotCache.set(normalized.id, { snapshot: next, diagnostics: next.diagnostics || [], nextSeq: seq + 1 });
57
57
  writeSnapshot(snapshotPath, next);
@@ -92,15 +92,15 @@ function normalizeEvent(event, fallbackId) {
92
92
  }
93
93
 
94
94
  function getJournalPath(rootDir, id) {
95
- return path.join(rootDir, safeSessionId(id) + '.jsonl');
95
+ return path.join(rootDir, `${safeSessionId(id)}.jsonl`);
96
96
  }
97
97
 
98
98
  function getSnapshotPath(rootDir, id) {
99
- return path.join(rootDir, safeSessionId(id) + '.snapshot.json');
99
+ return path.join(rootDir, `${safeSessionId(id)}.snapshot.json`);
100
100
  }
101
101
 
102
102
  function safeSessionId(id) {
103
- if (!/^[A-Za-z0-9_-]{1,128}$/.test(id)) throw new Error('invalid session id: ' + id);
103
+ if (!/^[A-Za-z0-9_-]{1,128}$/.test(id)) throw new Error(`invalid session id: ${id}`);
104
104
  return id;
105
105
  }
106
106
 
@@ -289,5 +289,5 @@ function upsertArtifact(artifacts, artifact) {
289
289
  }
290
290
 
291
291
  function writeSnapshot(snapshotPath, snapshot) {
292
- fs.writeFileSync(snapshotPath, JSON.stringify(snapshot, null, 2) + '\n');
292
+ fs.writeFileSync(snapshotPath, `${JSON.stringify(snapshot, null, 2)}\n`);
293
293
  }
@@ -73,7 +73,7 @@ export function buildPropContract(expressions) {
73
73
 
74
74
  function derivePropName(expr, index) {
75
75
  const tail = expr.match(/(?:\.|\[)(\w+)\s*\]?$/);
76
- if (tail && tail[1] && /^[A-Za-z_$][\w$]*$/.test(tail[1])) {
76
+ if (tail?.[1] && /^[A-Za-z_$][\w$]*$/.test(tail[1])) {
77
77
  return tail[1];
78
78
  }
79
79
  return `prop${index}`;
@@ -166,7 +166,7 @@ export function scaffoldSvelteComponentSession({
166
166
  runtimeModule: `/${SVELTE_RUNTIME_FILE}`,
167
167
  };
168
168
 
169
- fs.writeFileSync(path.join(dir, 'manifest.json'), JSON.stringify(manifest, null, 2) + '\n', 'utf-8');
169
+ fs.writeFileSync(path.join(dir, 'manifest.json'), `${JSON.stringify(manifest, null, 2)}\n`, 'utf-8');
170
170
 
171
171
  for (let n = 1; n <= count; n++) {
172
172
  const variantFile = path.join(dir, `v${n}.svelte`);
@@ -216,7 +216,7 @@ export function scaffoldSvelteComponentInsertSession({
216
216
  runtimeModule: `/${SVELTE_RUNTIME_FILE}`,
217
217
  };
218
218
 
219
- fs.writeFileSync(path.join(dir, 'manifest.json'), JSON.stringify(manifest, null, 2) + '\n', 'utf-8');
219
+ fs.writeFileSync(path.join(dir, 'manifest.json'), `${JSON.stringify(manifest, null, 2)}\n`, 'utf-8');
220
220
 
221
221
  for (let n = 1; n <= count; n++) {
222
222
  const variantFile = path.join(dir, `v${n}.svelte`);
@@ -270,14 +270,14 @@ export function resolveSourceFile(sourceFile, cwd = process.cwd()) {
270
270
  throw new Error('Svelte-component source file escapes project root');
271
271
  }
272
272
  if (!fs.existsSync(full)) {
273
- throw new Error('Svelte-component source file not found: ' + sourceFile);
273
+ throw new Error(`Svelte-component source file not found: ${sourceFile}`);
274
274
  }
275
275
  return full;
276
276
  }
277
277
 
278
278
  function appendCssToSvelteStyle(lines, cssLines) {
279
279
  const closeIdx = findLastStyleCloseLine(lines);
280
- const prepared = ['', ...cssLines.map((line) => (line.trim() === '' ? '' : ' ' + line.trimStart()))];
280
+ const prepared = ['', ...cssLines.map((line) => (line.trim() === '' ? '' : ` ${line.trimStart()}`))];
281
281
  if (closeIdx === -1) {
282
282
  return [...lines, '', '<style>', ...prepared.slice(1), '</style>'];
283
283
  }
@@ -436,7 +436,7 @@ function rewriteAcceptedSvelteSelectorPart(selector, variantNum, paramValues, ro
436
436
  function rewriteParamSelectors(selector, paramValues) {
437
437
  let keep = true;
438
438
  const next = selector.replace(/\[data-p-([A-Za-z0-9_-]+)(?:=(["'])(.*?)\2)?\]/g, (_match, key, _quote, expected) => {
439
- if (!paramValues || !Object.prototype.hasOwnProperty.call(paramValues, key)) return '';
439
+ if (!paramValues || !Object.hasOwn(paramValues, key)) return '';
440
440
  const actual = paramValues[key];
441
441
  if (expected != null && String(actual) !== String(expected)) {
442
442
  keep = false;
@@ -537,7 +537,7 @@ export function inlineSvelteComponentAccept(manifest, variantNum, paramValues =
537
537
  const start = Number(manifest.sourceStartLine) - 1;
538
538
  const end = Number(manifest.sourceEndLine) - 1;
539
539
  if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end < start || end >= sourceLines.length) {
540
- return { handled: false, error: 'Invalid source line range for ' + manifest.sourceFile, ...resultBase };
540
+ return { handled: false, error: `Invalid source line range for ${manifest.sourceFile}`, ...resultBase };
541
541
  }
542
542
 
543
543
  const indent = sourceLines[start].match(/^(\s*)/)?.[1] || '';
@@ -561,7 +561,7 @@ export function inlineSvelteComponentAccept(manifest, variantNum, paramValues =
561
561
  try {
562
562
  fs.writeFileSync(sourceFile, newLines.join('\n'), 'utf-8');
563
563
  } catch (err) {
564
- return { handled: false, error: 'Failed to write Svelte source: ' + err.message, ...resultBase };
564
+ return { handled: false, error: `Failed to write Svelte source: ${err.message}`, ...resultBase };
565
565
  }
566
566
  removeSvelteComponentSession(manifest.id, cwd);
567
567
 
@@ -596,7 +596,7 @@ function inlineSvelteComponentInsertAccept({
596
596
  const sourceLines = sourceContent.split('\n');
597
597
  const insertIndex = Number(manifest.insertLine) - 1;
598
598
  if (!Number.isInteger(insertIndex) || insertIndex < 0 || insertIndex > sourceLines.length) {
599
- return { handled: false, error: 'Invalid insert line for ' + manifest.sourceFile, ...resultBase };
599
+ return { handled: false, error: `Invalid insert line for ${manifest.sourceFile}`, ...resultBase };
600
600
  }
601
601
 
602
602
  const nearbyLine = sourceLines[insertIndex] ?? sourceLines[insertIndex - 1] ?? '';
@@ -621,7 +621,7 @@ function inlineSvelteComponentInsertAccept({
621
621
  try {
622
622
  fs.writeFileSync(sourceFile, newLines.join('\n'), 'utf-8');
623
623
  } catch (err) {
624
- return { handled: false, error: 'Failed to write Svelte source: ' + err.message, ...resultBase };
624
+ return { handled: false, error: `Failed to write Svelte source: ${err.message}`, ...resultBase };
625
625
  }
626
626
  removeSvelteComponentSession(manifest.id, cwd);
627
627
 
@@ -675,7 +675,7 @@ function mergeOriginalTopLevelAttrs(markup, originalMarkup) {
675
675
  const nextOpen = variantOpen.prefix
676
676
  + variantOpen.tag
677
677
  + attrs
678
- + additions.map((attr) => ' ' + attr.trim()).join('')
678
+ + additions.map((attr) => ` ${attr.trim()}`).join('')
679
679
  + variantOpen.close;
680
680
  return markup.slice(0, variantOpen.index) + nextOpen + markup.slice(variantOpen.index + variantOpen.raw.length);
681
681
  }
@@ -761,7 +761,7 @@ export function writeDeferredAccept(entry, cwd = process.cwd()) {
761
761
  const data = readDeferredAccepts(cwd);
762
762
  data.accepts = (data.accepts || []).filter((item) => item.id !== entry.id);
763
763
  data.accepts.push({ ...entry, createdAt: new Date().toISOString() });
764
- fs.writeFileSync(file, JSON.stringify(data, null, 2) + '\n', 'utf-8');
764
+ fs.writeFileSync(file, `${JSON.stringify(data, null, 2)}\n`, 'utf-8');
765
765
  }
766
766
 
767
767
  export function applyDeferredSvelteComponentAccepts(cwd = process.cwd()) {
@@ -792,7 +792,7 @@ export function applyDeferredSvelteComponentAccepts(cwd = process.cwd()) {
792
792
  }
793
793
  }
794
794
  if (remaining.length > 0) {
795
- fs.writeFileSync(file, JSON.stringify({ accepts: remaining }, null, 2) + '\n', 'utf-8');
795
+ fs.writeFileSync(file, `${JSON.stringify({ accepts: remaining }, null, 2)}\n`, 'utf-8');
796
796
  } else {
797
797
  try { fs.rmSync(file, { force: true }); } catch {}
798
798
  }
@@ -103,9 +103,9 @@ export function patchSvelteLayout(content) {
103
103
  const scriptMatch = out.match(/<script(?:\s[^>]*)?>/i);
104
104
  if (scriptMatch) {
105
105
  const insertAt = scriptMatch.index + scriptMatch[0].length;
106
- out = out.slice(0, insertAt) + '\n ' + SVELTE_ROOT_IMPORT + out.slice(insertAt);
106
+ out = `${out.slice(0, insertAt)}\n ${SVELTE_ROOT_IMPORT}${out.slice(insertAt)}`;
107
107
  } else {
108
- out = `<script>\n ${SVELTE_ROOT_IMPORT}\n</script>\n\n` + out;
108
+ out = `<script>\n ${SVELTE_ROOT_IMPORT}\n</script>\n\n${out}`;
109
109
  }
110
110
  }
111
111
 
@@ -117,7 +117,7 @@ export function patchSvelteLayout(content) {
117
117
  if (match) {
118
118
  out = out.slice(0, match.index) + block + out.slice(match.index);
119
119
  } else {
120
- out = out.replace(/\s*$/, '\n\n' + block);
120
+ out = out.replace(/\s*$/, `\n\n${block}`);
121
121
  }
122
122
  }
123
123
 
@@ -134,7 +134,7 @@ export function unpatchSvelteLayout(content) {
134
134
  'g',
135
135
  );
136
136
  out = out.replace(blockRe, '$1');
137
- out = out.replace(new RegExp('^\\s*' + escapeRegExp(SVELTE_ROOT_IMPORT) + '\\s*\\n?', 'gm'), '');
137
+ out = out.replace(new RegExp(`^\\s*${escapeRegExp(SVELTE_ROOT_IMPORT)}\\s*\\n?`, 'gm'), '');
138
138
  out = out.replace(/<script>\s*<\/script>\s*\n?/g, '');
139
139
  return out.replace(/\n{3,}/g, '\n\n');
140
140
  }
@@ -140,7 +140,7 @@ export function getLiveUiElementById(id, env = globalThis) {
140
140
  if (found) return found;
141
141
  }
142
142
  if (root?.querySelector) {
143
- const found = root.querySelector('#' + escapeCssIdent(id));
143
+ const found = root.querySelector(`#${escapeCssIdent(id)}`);
144
144
  if (found) return found;
145
145
  }
146
146
  return doc?.getElementById?.(id) || null;
@@ -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() {