@antigenic-oss/paint 0.2.0 → 0.2.2

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 (65) hide show
  1. package/README.md +32 -17
  2. package/bin/bridge-server.js +38 -0
  3. package/bin/paint.js +559 -104
  4. package/bin/terminal-server.js +105 -0
  5. package/package.json +7 -8
  6. package/public/dev-editor-inspector.js +92 -104
  7. package/src/app/api/claude/apply/route.ts +2 -2
  8. package/src/app/api/project/scan/route.ts +1 -1
  9. package/src/app/api/proxy/[[...path]]/route.ts +4 -4
  10. package/src/app/docs/DocsClient.tsx +1 -1
  11. package/src/app/docs/page.tsx +0 -1
  12. package/src/app/page.tsx +1 -1
  13. package/src/bridge/api-handlers.ts +1 -1
  14. package/src/bridge/proxy-handler.ts +4 -4
  15. package/src/bridge/server.ts +135 -39
  16. package/src/components/ConnectModal.tsx +1 -2
  17. package/src/components/PreviewFrame.tsx +2 -2
  18. package/src/components/ResponsiveToolbar.tsx +1 -2
  19. package/src/components/common/ColorPicker.tsx +7 -9
  20. package/src/components/common/UnitInput.tsx +1 -1
  21. package/src/components/common/VariableColorPicker.tsx +0 -1
  22. package/src/components/left-panel/ComponentsPanel.tsx +3 -3
  23. package/src/components/left-panel/LayerNode.tsx +1 -1
  24. package/src/components/left-panel/icons.tsx +1 -1
  25. package/src/components/left-panel/terminal/TerminalPanel.tsx +2 -2
  26. package/src/components/right-panel/ElementLogBox.tsx +1 -3
  27. package/src/components/right-panel/changes/ChangesPanel.tsx +12 -12
  28. package/src/components/right-panel/claude/ClaudeIntegrationPanel.tsx +2 -2
  29. package/src/components/right-panel/claude/DiffViewer.tsx +1 -1
  30. package/src/components/right-panel/claude/ProjectRootSelector.tsx +7 -7
  31. package/src/components/right-panel/claude/SetupFlow.tsx +1 -1
  32. package/src/components/right-panel/console/ConsolePanel.tsx +4 -4
  33. package/src/components/right-panel/design/BackgroundSection.tsx +2 -2
  34. package/src/components/right-panel/design/GradientEditor.tsx +6 -6
  35. package/src/components/right-panel/design/LayoutSection.tsx +4 -4
  36. package/src/components/right-panel/design/PositionSection.tsx +2 -2
  37. package/src/components/right-panel/design/SVGSection.tsx +2 -3
  38. package/src/components/right-panel/design/ShadowBlurSection.tsx +5 -5
  39. package/src/components/right-panel/design/TextSection.tsx +5 -5
  40. package/src/components/right-panel/design/icons.tsx +1 -1
  41. package/src/components/right-panel/design/inputs/BoxModelPreview.tsx +2 -2
  42. package/src/components/right-panel/design/inputs/CompactInput.tsx +2 -2
  43. package/src/components/right-panel/design/inputs/DraggableLabel.tsx +2 -1
  44. package/src/components/right-panel/design/inputs/IconToggleGroup.tsx +1 -1
  45. package/src/components/right-panel/design/inputs/LinkedInputPair.tsx +3 -3
  46. package/src/components/right-panel/design/inputs/SectionHeader.tsx +2 -1
  47. package/src/hooks/useDOMTree.ts +0 -1
  48. package/src/hooks/usePostMessage.ts +4 -3
  49. package/src/hooks/useTargetUrl.ts +1 -1
  50. package/src/inspector/DOMTraverser.ts +2 -2
  51. package/src/inspector/HoverHighlighter.ts +6 -6
  52. package/src/inspector/SelectionHighlighter.ts +4 -4
  53. package/src/lib/classifyElement.ts +1 -2
  54. package/src/lib/claude-bin.ts +1 -1
  55. package/src/lib/clientProjectScanner.ts +13 -13
  56. package/src/lib/cssVariableUtils.ts +1 -1
  57. package/src/lib/folderPicker.ts +4 -1
  58. package/src/lib/projectScanner.ts +15 -15
  59. package/src/lib/tailwindClassParser.ts +1 -1
  60. package/src/lib/textShadowUtils.ts +1 -1
  61. package/src/lib/utils.ts +4 -4
  62. package/src/proxy.ts +1 -1
  63. package/src/store/treeSlice.ts +2 -2
  64. package/src/server/terminal-server.ts +0 -104
  65. package/tsconfig.server.json +0 -12
@@ -16,7 +16,7 @@
16
16
  * If detection fails, it discovers the editor via handshake.
17
17
  * It does nothing when the page is not loaded inside an iframe.
18
18
  */
19
- ;(function () {
19
+ ;(() => {
20
20
  // Iframe guard — script does nothing if not loaded inside an iframe
21
21
  if (window.parent === window) return
22
22
 
@@ -30,7 +30,7 @@
30
30
  try {
31
31
  // Same-origin: can access parent's location directly
32
32
  parentOrigin = window.parent.location.origin
33
- } catch (e) {
33
+ } catch (_e) {
34
34
  // Cross-origin: can't access parent's origin.
35
35
  // Use '*' — safe for localhost dev tool use case.
36
36
  parentOrigin = '*'
@@ -42,7 +42,7 @@
42
42
  function send(message) {
43
43
  try {
44
44
  window.parent.postMessage(message, parentOrigin)
45
- } catch (e) {}
45
+ } catch (_e) {}
46
46
  }
47
47
 
48
48
  // --- Console Interception (no DOM dependency, runs immediately) ---
@@ -61,7 +61,7 @@
61
61
  if (arg instanceof Error) return arg.stack || arg.message || String(arg)
62
62
  try {
63
63
  return JSON.stringify(arg)
64
- } catch (e) {
64
+ } catch (_e) {
65
65
  return String(arg)
66
66
  }
67
67
  }
@@ -85,7 +85,7 @@
85
85
  interceptConsole('warn')
86
86
  interceptConsole('error')
87
87
 
88
- window.onerror = function (message, source, line, column) {
88
+ window.onerror = (message, source, line, column) => {
89
89
  send({
90
90
  type: 'CONSOLE_MESSAGE',
91
91
  payload: {
@@ -99,7 +99,7 @@
99
99
  })
100
100
  }
101
101
 
102
- window.addEventListener('unhandledrejection', function (e) {
102
+ window.addEventListener('unhandledrejection', (e) => {
103
103
  var reason = e.reason
104
104
  var msg =
105
105
  reason instanceof Error
@@ -109,7 +109,7 @@
109
109
  type: 'CONSOLE_MESSAGE',
110
110
  payload: {
111
111
  level: 'error',
112
- args: ['Unhandled Promise Rejection: ' + msg],
112
+ args: [`Unhandled Promise Rejection: ${msg}`],
113
113
  timestamp: Date.now(),
114
114
  },
115
115
  })
@@ -118,15 +118,11 @@
118
118
  // --- Inspector initialization (requires document.body) ---
119
119
  function initInspector() {
120
120
  function kebabToCamel(str) {
121
- return str.replace(/-([a-z])/g, function (m, c) {
122
- return c.toUpperCase()
123
- })
121
+ return str.replace(/-([a-z])/g, (_m, c) => c.toUpperCase())
124
122
  }
125
123
 
126
124
  function camelToKebab(str) {
127
- return str.replace(/[A-Z]/g, function (c) {
128
- return '-' + c.toLowerCase()
129
- })
125
+ return str.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`)
130
126
  }
131
127
 
132
128
  function generateSelectorPath(element) {
@@ -135,7 +131,7 @@
135
131
  while (current && current !== document.documentElement) {
136
132
  var selector = current.tagName.toLowerCase()
137
133
  if (current.id) {
138
- selector += '#' + CSS.escape(current.id)
134
+ selector += `#${CSS.escape(current.id)}`
139
135
  parts.unshift(selector)
140
136
  break
141
137
  }
@@ -145,20 +141,16 @@
145
141
  selector +=
146
142
  '.' +
147
143
  classes
148
- .map(function (c) {
149
- return CSS.escape(c)
150
- })
144
+ .map((c) => CSS.escape(c))
151
145
  .join('.')
152
146
  }
153
147
  }
154
148
  var parent = current.parentElement
155
149
  if (parent) {
156
- var siblings = Array.from(parent.children).filter(function (c) {
157
- return c.tagName === current.tagName
158
- })
150
+ var siblings = Array.from(parent.children).filter((c) => c.tagName === current.tagName)
159
151
  if (siblings.length > 1) {
160
152
  var index = siblings.indexOf(current) + 1
161
- selector += ':nth-of-type(' + index + ')'
153
+ selector += `:nth-of-type(${index})`
162
154
  }
163
155
  }
164
156
  parts.unshift(selector)
@@ -300,9 +292,7 @@
300
292
  for (var si = 0; si < document.styleSheets.length; si++) {
301
293
  var sheet = document.styleSheets[si]
302
294
  if (
303
- sheet.ownerNode &&
304
- sheet.ownerNode.hasAttribute &&
305
- sheet.ownerNode.hasAttribute('data-design-tokens')
295
+ sheet.ownerNode?.hasAttribute?.('data-design-tokens')
306
296
  ) {
307
297
  taggedSheets.push(sheet)
308
298
  }
@@ -314,7 +304,7 @@
314
304
  var taggedRules
315
305
  try {
316
306
  taggedRules = taggedSheets[ti].cssRules || taggedSheets[ti].rules
317
- } catch (e) {
307
+ } catch (_e) {
318
308
  continue
319
309
  }
320
310
  if (taggedRules) extractFromRules(taggedRules)
@@ -328,7 +318,7 @@
328
318
  var fallbackRules
329
319
  try {
330
320
  fallbackRules = fallbackSheet.cssRules || fallbackSheet.rules
331
- } catch (e) {
321
+ } catch (_e) {
332
322
  continue
333
323
  }
334
324
  if (fallbackRules) extractFromRules(fallbackRules)
@@ -394,7 +384,7 @@
394
384
  var rules
395
385
  try {
396
386
  rules = sheet.cssRules || sheet.rules
397
- } catch (e) {
387
+ } catch (_e) {
398
388
  continue
399
389
  }
400
390
  if (!rules) continue
@@ -404,7 +394,7 @@
404
394
  var matches = false
405
395
  try {
406
396
  matches = el.matches(rule.selectorText)
407
- } catch (e) {
397
+ } catch (_e) {
408
398
  continue
409
399
  }
410
400
  if (!matches) continue
@@ -443,20 +433,20 @@
443
433
 
444
434
  function getElementLabel(el) {
445
435
  var tag = el.tagName.toLowerCase()
446
- if (el.id) return tag + '#' + el.id
436
+ if (el.id) return `${tag}#${el.id}`
447
437
  var cls = el.className
448
438
  if (cls && typeof cls === 'string') {
449
439
  var classes = cls.trim().split(/\s+/)
450
440
  // Prefer c- prefixed class for the label
451
441
  for (var i = 0; i < classes.length; i++) {
452
- if (classes[i].indexOf('c-') === 0) return tag + '.' + classes[i]
442
+ if (classes[i].indexOf('c-') === 0) return `${tag}.${classes[i]}`
453
443
  }
454
- if (classes[0]) return tag + '.' + classes[0]
444
+ if (classes[0]) return `${tag}.${classes[0]}`
455
445
  }
456
446
  return tag
457
447
  }
458
448
 
459
- document.addEventListener('mousemove', function (e) {
449
+ document.addEventListener('mousemove', (e) => {
460
450
  if (!selectionModeEnabled) {
461
451
  hoverOverlay.style.display = 'none'
462
452
  return
@@ -478,10 +468,10 @@
478
468
  hoveredElement = el
479
469
  var rect = el.getBoundingClientRect()
480
470
  hoverOverlay.style.display = 'block'
481
- hoverOverlay.style.top = rect.top + 'px'
482
- hoverOverlay.style.left = rect.left + 'px'
483
- hoverOverlay.style.width = rect.width + 'px'
484
- hoverOverlay.style.height = rect.height + 'px'
471
+ hoverOverlay.style.top = `${rect.top}px`
472
+ hoverOverlay.style.left = `${rect.left}px`
473
+ hoverOverlay.style.width = `${rect.width}px`
474
+ hoverOverlay.style.height = `${rect.height}px`
485
475
  hoverLabel.textContent = getElementLabel(el)
486
476
  if (rect.top < 20) {
487
477
  hoverLabel.style.top = 'auto'
@@ -501,7 +491,7 @@
501
491
  // When off, let clicks through so links and buttons work normally.
502
492
  document.addEventListener(
503
493
  'click',
504
- function (e) {
494
+ (e) => {
505
495
  if (!selectionModeEnabled) return
506
496
 
507
497
  // If text editing is active, clicking outside commits the edit
@@ -537,10 +527,10 @@
537
527
  selectedElement = el
538
528
  var rect = el.getBoundingClientRect()
539
529
  selectionOverlay.style.display = 'block'
540
- selectionOverlay.style.top = rect.top + 'px'
541
- selectionOverlay.style.left = rect.left + 'px'
542
- selectionOverlay.style.width = rect.width + 'px'
543
- selectionOverlay.style.height = rect.height + 'px'
530
+ selectionOverlay.style.top = `${rect.top}px`
531
+ selectionOverlay.style.left = `${rect.left}px`
532
+ selectionOverlay.style.width = `${rect.width}px`
533
+ selectionOverlay.style.height = `${rect.height}px`
544
534
 
545
535
  var attrs = {}
546
536
  for (var ai = 0; ai < el.attributes.length; ai++) {
@@ -587,10 +577,10 @@
587
577
  function updateSelectionOverlay() {
588
578
  if (!selectedElement || selectionOverlay.style.display === 'none') return
589
579
  var rect = selectedElement.getBoundingClientRect()
590
- selectionOverlay.style.top = rect.top + 'px'
591
- selectionOverlay.style.left = rect.left + 'px'
592
- selectionOverlay.style.width = rect.width + 'px'
593
- selectionOverlay.style.height = rect.height + 'px'
580
+ selectionOverlay.style.top = `${rect.top}px`
581
+ selectionOverlay.style.left = `${rect.left}px`
582
+ selectionOverlay.style.width = `${rect.width}px`
583
+ selectionOverlay.style.height = `${rect.height}px`
594
584
  }
595
585
  window.addEventListener('scroll', updateSelectionOverlay, true)
596
586
  window.addEventListener('resize', updateSelectionOverlay, true)
@@ -677,7 +667,7 @@
677
667
  if (!el || SKIP_TEXT_EDIT_TAGS[el.tagName]) return null
678
668
  // Leaf node with text — ideal target
679
669
  if (el.children.length === 0) {
680
- return el.textContent && el.textContent.trim() ? el : null
670
+ return el.textContent?.trim() ? el : null
681
671
  }
682
672
  // Single child — recurse into it (common: <button><span>text</span></button>)
683
673
  if (el.children.length === 1) {
@@ -693,7 +683,7 @@
693
683
  for (var i = 0; i < el.children.length; i++) {
694
684
  var ch = el.children[i]
695
685
  if (SKIP_TEXT_EDIT_TAGS[ch.tagName]) continue
696
- if (ch.textContent && ch.textContent.trim()) {
686
+ if (ch.textContent?.trim()) {
697
687
  if (textChild) {
698
688
  textChild = null
699
689
  break
@@ -720,7 +710,7 @@
720
710
 
721
711
  document.addEventListener(
722
712
  'dblclick',
723
- function (e) {
713
+ (e) => {
724
714
  if (!selectionModeEnabled) return
725
715
  e.preventDefault()
726
716
  e.stopPropagation()
@@ -772,7 +762,7 @@
772
762
 
773
763
  document.addEventListener(
774
764
  'keydown',
775
- function (e) {
765
+ (e) => {
776
766
  if (textEditingActive) {
777
767
  e.stopPropagation()
778
768
  if (e.key === 'Enter' && !e.shiftKey) {
@@ -882,9 +872,7 @@
882
872
  // Convert kebab-case to Title Case (e.g. "nav-bar" → "Nav Bar")
883
873
  var name = raw
884
874
  .split('-')
885
- .map(function (part) {
886
- return part.charAt(0).toUpperCase() + part.slice(1)
887
- })
875
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
888
876
  .join(' ')
889
877
  return { name: name, method: 'c-prefix' }
890
878
  }
@@ -950,7 +938,7 @@
950
938
  }
951
939
  }
952
940
  for (var base in prefixes) {
953
- if (!prefixes.hasOwnProperty(base)) continue
941
+ if (!Object.hasOwn(prefixes, base)) continue
954
942
  var sizeOpts = [],
955
943
  colorOpts = [],
956
944
  stateOpts = []
@@ -960,20 +948,20 @@
960
948
  var rules
961
949
  try {
962
950
  rules = sheet.cssRules || sheet.rules
963
- } catch (e) {
951
+ } catch (_e) {
964
952
  continue
965
953
  }
966
954
  if (!rules) continue
967
955
  for (var ri = 0; ri < rules.length; ri++) {
968
956
  var rule = rules[ri]
969
957
  if (!rule.selectorText) continue
970
- var escapedBase = base.replace(/[-\/\\^*+?.()|[\]]/g, '\\$&')
958
+ var escapedBase = base.replace(/[-/\\^*+?.()|[\]]/g, '\\$&')
971
959
  var match = rule.selectorText.match(
972
- new RegExp('\\.' + escapedBase + '-([\\w-]+)'),
960
+ new RegExp(`\\.${escapedBase}-([\\w-]+)`),
973
961
  )
974
962
  if (!match) continue
975
963
  var foundSuffix = match[1]
976
- var foundClass = base + '-' + foundSuffix
964
+ var foundClass = `${base}-${foundSuffix}`
977
965
  if (foundClass === currentClass) continue
978
966
  var opt = {
979
967
  label: foundSuffix,
@@ -1002,7 +990,7 @@
1002
990
  if (sizeOpts.length > 0) {
1003
991
  sizeOpts.unshift(currentOpt)
1004
992
  var seen = {}
1005
- sizeOpts = sizeOpts.filter(function (o) {
993
+ sizeOpts = sizeOpts.filter((o) => {
1006
994
  if (seen[o.className]) return false
1007
995
  seen[o.className] = true
1008
996
  return true
@@ -1023,7 +1011,7 @@
1023
1011
  if (colorOpts.length > 0) {
1024
1012
  colorOpts.unshift(currentOpt)
1025
1013
  var seenC = {}
1026
- colorOpts = colorOpts.filter(function (o) {
1014
+ colorOpts = colorOpts.filter((o) => {
1027
1015
  if (seenC[o.className]) return false
1028
1016
  seenC[o.className] = true
1029
1017
  return true
@@ -1044,7 +1032,7 @@
1044
1032
  if (stateOpts.length > 0) {
1045
1033
  stateOpts.unshift(currentOpt)
1046
1034
  var seenS = {}
1047
- stateOpts = stateOpts.filter(function (o) {
1035
+ stateOpts = stateOpts.filter((o) => {
1048
1036
  if (seenS[o.className]) return false
1049
1037
  seenS[o.className] = true
1050
1038
  return true
@@ -1091,7 +1079,7 @@
1091
1079
  ]
1092
1080
  for (var pi = 0; pi < pseudos.length; pi++) {
1093
1081
  var pseudo = pseudos[pi]
1094
- var pseudoStyles = window.getComputedStyle(el, ':' + pseudo)
1082
+ var pseudoStyles = window.getComputedStyle(el, `:${pseudo}`)
1095
1083
  var diffs = {}
1096
1084
  var hasDiff = false
1097
1085
  for (var vi = 0; vi < visualProps.length; vi++) {
@@ -1123,7 +1111,7 @@
1123
1111
  },
1124
1112
  ]
1125
1113
  }
1126
- } catch (e) {}
1114
+ } catch (_e) {}
1127
1115
  return []
1128
1116
  }
1129
1117
 
@@ -1134,12 +1122,12 @@
1134
1122
  var index = 0
1135
1123
  var scheduleNext =
1136
1124
  typeof requestIdleCallback === 'function'
1137
- ? function (cb) {
1125
+ ? ((cb) => {
1138
1126
  requestIdleCallback(cb)
1139
- }
1140
- : function (cb) {
1127
+ })
1128
+ : ((cb) => {
1141
1129
  setTimeout(cb, 0)
1142
- }
1130
+ })
1143
1131
 
1144
1132
  function processBatch() {
1145
1133
  var end = Math.min(index + batchSize, allElements.length)
@@ -1198,10 +1186,10 @@
1198
1186
  // MutationObserver for DOM changes
1199
1187
  var mutationPending = false
1200
1188
  var previousTreeJSON = ''
1201
- var observer = new MutationObserver(function () {
1189
+ var observer = new MutationObserver(() => {
1202
1190
  if (mutationPending) return
1203
1191
  mutationPending = true
1204
- requestAnimationFrame(function () {
1192
+ requestAnimationFrame(() => {
1205
1193
  mutationPending = false
1206
1194
  var tree = serializeTree(document.body)
1207
1195
  if (!tree) return
@@ -1250,7 +1238,7 @@
1250
1238
 
1251
1239
  document.addEventListener(
1252
1240
  'dragover',
1253
- function (e) {
1241
+ (e) => {
1254
1242
  if (!e.dataTransfer || !e.dataTransfer.types.indexOf) return
1255
1243
  if (
1256
1244
  e.dataTransfer.types.indexOf('application/x-dev-editor-element') ===
@@ -1263,10 +1251,10 @@
1263
1251
  if (!dropTarget || dropTarget === dropIndicator) return
1264
1252
  if (dropTarget.id && dropTarget.id.indexOf('dev-editor') === 0) return
1265
1253
  var rect = dropTarget.getBoundingClientRect()
1266
- dropIndicator.style.top = rect.top + 'px'
1267
- dropIndicator.style.left = rect.left + 'px'
1268
- dropIndicator.style.width = rect.width + 'px'
1269
- dropIndicator.style.height = rect.height + 'px'
1254
+ dropIndicator.style.top = `${rect.top}px`
1255
+ dropIndicator.style.left = `${rect.left}px`
1256
+ dropIndicator.style.width = `${rect.width}px`
1257
+ dropIndicator.style.height = `${rect.height}px`
1270
1258
  dropIndicator.style.display = 'block'
1271
1259
  },
1272
1260
  true,
@@ -1274,7 +1262,7 @@
1274
1262
 
1275
1263
  document.addEventListener(
1276
1264
  'dragleave',
1277
- function (e) {
1265
+ (e) => {
1278
1266
  if (
1279
1267
  e.relatedTarget === null ||
1280
1268
  e.relatedTarget === document.documentElement
@@ -1287,7 +1275,7 @@
1287
1275
 
1288
1276
  document.addEventListener(
1289
1277
  'drop',
1290
- function (e) {
1278
+ (e) => {
1291
1279
  dropIndicator.style.display = 'none'
1292
1280
  if (!e.dataTransfer) return
1293
1281
  var raw = e.dataTransfer.getData('application/x-dev-editor-element')
@@ -1311,7 +1299,7 @@
1311
1299
  if (data.defaultStyles) {
1312
1300
  var dndDS = data.defaultStyles
1313
1301
  for (var dndDSKey in dndDS) {
1314
- if (dndDS.hasOwnProperty(dndDSKey))
1302
+ if (Object.hasOwn(dndDS, dndDSKey))
1315
1303
  newEl.style.setProperty(dndDSKey, dndDS[dndDSKey])
1316
1304
  }
1317
1305
  }
@@ -1333,13 +1321,13 @@
1333
1321
  defaultStyles: data.defaultStyles || undefined,
1334
1322
  },
1335
1323
  })
1336
- } catch (err) {}
1324
+ } catch (_err) {}
1337
1325
  },
1338
1326
  true,
1339
1327
  )
1340
1328
 
1341
1329
  // --- Handle messages from editor ---
1342
- window.addEventListener('message', function (e) {
1330
+ window.addEventListener('message', (e) => {
1343
1331
  // Accept messages from detected parentOrigin, or any origin if using wildcard
1344
1332
  if (parentOrigin !== '*' && e.origin !== parentOrigin) return
1345
1333
 
@@ -1364,7 +1352,7 @@
1364
1352
  selectElement(el)
1365
1353
  el.scrollIntoView({ block: 'center', behavior: 'instant' })
1366
1354
  }
1367
- } catch (err) {}
1355
+ } catch (_err) {}
1368
1356
  break
1369
1357
  }
1370
1358
  case 'PREVIEW_CHANGE': {
@@ -1372,7 +1360,7 @@
1372
1360
  var target = document.querySelector(msg.payload.selectorPath)
1373
1361
  if (target) {
1374
1362
  var cssProp = camelToKebab(msg.payload.property)
1375
- requestAnimationFrame(function () {
1363
+ requestAnimationFrame(() => {
1376
1364
  target.style.setProperty(
1377
1365
  cssProp,
1378
1366
  msg.payload.value,
@@ -1380,7 +1368,7 @@
1380
1368
  )
1381
1369
  })
1382
1370
  }
1383
- } catch (err) {}
1371
+ } catch (_err) {}
1384
1372
  break
1385
1373
  }
1386
1374
  case 'REVERT_CHANGE': {
@@ -1388,12 +1376,12 @@
1388
1376
  var target2 = document.querySelector(msg.payload.selectorPath)
1389
1377
  if (target2)
1390
1378
  target2.style.removeProperty(camelToKebab(msg.payload.property))
1391
- } catch (err) {}
1379
+ } catch (_err) {}
1392
1380
  break
1393
1381
  }
1394
1382
  case 'REVERT_ALL': {
1395
1383
  var allElements = document.querySelectorAll('[style]')
1396
- allElements.forEach(function (el) {
1384
+ allElements.forEach((el) => {
1397
1385
  el.removeAttribute('style')
1398
1386
  })
1399
1387
  break
@@ -1420,10 +1408,10 @@
1420
1408
  case 'SHOW_SELECTION_OVERLAY': {
1421
1409
  if (selectionModeEnabled && selectedElement) {
1422
1410
  var sr = selectedElement.getBoundingClientRect()
1423
- selectionOverlay.style.top = sr.top + 'px'
1424
- selectionOverlay.style.left = sr.left + 'px'
1425
- selectionOverlay.style.width = sr.width + 'px'
1426
- selectionOverlay.style.height = sr.height + 'px'
1411
+ selectionOverlay.style.top = `${sr.top}px`
1412
+ selectionOverlay.style.left = `${sr.left}px`
1413
+ selectionOverlay.style.width = `${sr.width}px`
1414
+ selectionOverlay.style.height = `${sr.height}px`
1427
1415
  selectionOverlay.style.display = 'block'
1428
1416
  }
1429
1417
  break
@@ -1446,7 +1434,7 @@
1446
1434
  var resolved
1447
1435
  try {
1448
1436
  resolved = new URL(rawHref, window.location.origin)
1449
- } catch (e) {
1437
+ } catch (_e) {
1450
1438
  continue
1451
1439
  }
1452
1440
  if (resolved.origin !== window.location.origin) continue
@@ -1474,12 +1462,12 @@
1474
1462
  case 'REQUEST_COMPONENTS': {
1475
1463
  try {
1476
1464
  var compRoot = document.body
1477
- if (msg.payload && msg.payload.rootSelectorPath) {
1465
+ if (msg.payload?.rootSelectorPath) {
1478
1466
  var rootEl = document.querySelector(msg.payload.rootSelectorPath)
1479
1467
  if (rootEl) compRoot = rootEl
1480
1468
  }
1481
1469
  scanForComponents(compRoot)
1482
- } catch (err) {}
1470
+ } catch (_err) {}
1483
1471
  break
1484
1472
  }
1485
1473
  case 'APPLY_VARIANT': {
@@ -1535,7 +1523,7 @@
1535
1523
  },
1536
1524
  })
1537
1525
  }
1538
- } catch (err) {}
1526
+ } catch (_err) {}
1539
1527
  break
1540
1528
  }
1541
1529
  case 'REVERT_VARIANT': {
@@ -1558,21 +1546,21 @@
1558
1546
  }
1559
1547
  }
1560
1548
  }
1561
- } catch (err) {}
1549
+ } catch (_err) {}
1562
1550
  break
1563
1551
  }
1564
1552
  case 'SET_TEXT_CONTENT': {
1565
1553
  try {
1566
1554
  var stEl = document.querySelector(msg.payload.selectorPath)
1567
1555
  if (stEl) stEl.textContent = msg.payload.text
1568
- } catch (err) {}
1556
+ } catch (_err) {}
1569
1557
  break
1570
1558
  }
1571
1559
  case 'REVERT_TEXT_CONTENT': {
1572
1560
  try {
1573
1561
  var rtEl = document.querySelector(msg.payload.selectorPath)
1574
1562
  if (rtEl) rtEl.textContent = msg.payload.originalText
1575
- } catch (err) {}
1563
+ } catch (_err) {}
1576
1564
  break
1577
1565
  }
1578
1566
  case 'DELETE_ELEMENT': {
@@ -1609,7 +1597,7 @@
1609
1597
  },
1610
1598
  })
1611
1599
  }
1612
- } catch (err) {}
1600
+ } catch (_err) {}
1613
1601
  break
1614
1602
  }
1615
1603
  case 'REVERT_DELETE': {
@@ -1618,7 +1606,7 @@
1618
1606
  if (rdEl) {
1619
1607
  rdEl.style.removeProperty('display')
1620
1608
  }
1621
- } catch (err) {}
1609
+ } catch (_err) {}
1622
1610
  break
1623
1611
  }
1624
1612
  case 'INSERT_ELEMENT': {
@@ -1656,7 +1644,7 @@
1656
1644
  if (msg.payload.defaultStyles) {
1657
1645
  var ieDS = msg.payload.defaultStyles
1658
1646
  for (var ieDSKey in ieDS) {
1659
- if (ieDS.hasOwnProperty(ieDSKey))
1647
+ if (Object.hasOwn(ieDS, ieDSKey))
1660
1648
  ieNew.style.setProperty(ieDSKey, ieDS[ieDSKey])
1661
1649
  }
1662
1650
  }
@@ -1679,16 +1667,16 @@
1679
1667
  },
1680
1668
  })
1681
1669
  }
1682
- } catch (err) {}
1670
+ } catch (_err) {}
1683
1671
  break
1684
1672
  }
1685
1673
  case 'REMOVE_INSERTED_ELEMENT': {
1686
1674
  try {
1687
1675
  var rieEl = document.querySelector(msg.payload.selectorPath)
1688
- if (rieEl && rieEl.parentElement) {
1676
+ if (rieEl?.parentElement) {
1689
1677
  rieEl.parentElement.removeChild(rieEl)
1690
1678
  }
1691
- } catch (err) {}
1679
+ } catch (_err) {}
1692
1680
  break
1693
1681
  }
1694
1682
  case 'MOVE_ELEMENT': {
@@ -1743,7 +1731,7 @@
1743
1731
  updateSelectionOverlay()
1744
1732
  }
1745
1733
  }
1746
- } catch (err) {}
1734
+ } catch (_err) {}
1747
1735
  break
1748
1736
  }
1749
1737
  case 'REVERT_MOVE_ELEMENT': {
@@ -1766,7 +1754,7 @@
1766
1754
  updateSelectionOverlay()
1767
1755
  }
1768
1756
  }
1769
- } catch (err) {}
1757
+ } catch (_err) {}
1770
1758
  break
1771
1759
  }
1772
1760
  case 'HEARTBEAT': {
@@ -1838,7 +1826,7 @@
1838
1826
  // If they don't fire (proxy context), this catches the stuck elements.
1839
1827
  // Re-run a few times to catch dynamically rendered content.
1840
1828
  var revealAttempts = 0
1841
- var revealTimer = setInterval(function () {
1829
+ var revealTimer = setInterval(() => {
1842
1830
  revealAnimationHidden()
1843
1831
  revealAttempts++
1844
1832
  if (revealAttempts >= 5) clearInterval(revealTimer)
@@ -1849,7 +1837,7 @@
1849
1837
  // This handles race conditions where the editor isn't listening yet.
1850
1838
  send({ type: 'INSPECTOR_READY' })
1851
1839
  var readyRetryCount = 0
1852
- var readyInterval = setInterval(function () {
1840
+ var readyInterval = setInterval(() => {
1853
1841
  if (connected) {
1854
1842
  clearInterval(readyInterval)
1855
1843
  return
@@ -82,7 +82,7 @@ function buildSummary(output: string, filesModified: string[]): string {
82
82
  return 'Changes applied. No specific file modifications detected in output.'
83
83
  }
84
84
  // Return the first 200 chars of the output as summary
85
- return trimmed.length > 200 ? trimmed.slice(0, 200) + '...' : trimmed
85
+ return trimmed.length > 200 ? `${trimmed.slice(0, 200)}...` : trimmed
86
86
  }
87
87
 
88
88
  return (
@@ -158,7 +158,7 @@ export async function POST(request: Request): Promise<NextResponse> {
158
158
  }
159
159
 
160
160
  // Combine stdout and stderr to look for file modification signals
161
- const combinedOutput = result.stdout + '\n' + result.stderr
161
+ const combinedOutput = `${result.stdout}\n${result.stderr}`
162
162
  const filesModified = extractModifiedFiles(combinedOutput)
163
163
  const summary = buildSummary(result.stdout, filesModified)
164
164
 
@@ -484,7 +484,7 @@ function scanAppRoutes(projectRoot: string): RouteEntry[] {
484
484
  .filter(Boolean)
485
485
  .filter((seg) => !seg.startsWith('('))
486
486
 
487
- const urlPattern = '/' + urlSegments.join('/')
487
+ const urlPattern = `/${urlSegments.join('/')}`
488
488
  const filePath = path.relative(projectRoot, fullPath)
489
489
 
490
490
  routes.push({