@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
@@ -89,7 +89,7 @@ function filePathToUrlPattern(relativePath: string): string {
89
89
  const parts = relativePath.split(path.sep)
90
90
  const routeParts = parts.slice(1, -1)
91
91
  const filtered = routeParts.filter((p) => !p.startsWith('('))
92
- return '/' + filtered.join('/')
92
+ return `/${filtered.join('/')}`
93
93
  }
94
94
 
95
95
  interface WalkCollectors {
@@ -155,12 +155,12 @@ function walkDir(
155
155
  (COMPONENT_EXTENSIONS.has(ext) || MAYBE_COMPONENT_EXTENSIONS.has(ext))
156
156
  ) {
157
157
  if (
158
- relativePath.startsWith('app' + path.sep) ||
159
- relativePath.startsWith('src' + path.sep + 'app' + path.sep)
158
+ relativePath.startsWith(`app${path.sep}`) ||
159
+ relativePath.startsWith(`src${path.sep}app${path.sep}`)
160
160
  ) {
161
161
  collectors.routes.push({
162
162
  urlPattern: filePathToUrlPattern(
163
- relativePath.startsWith('src' + path.sep)
163
+ relativePath.startsWith(`src${path.sep}`)
164
164
  ? relativePath.slice(4)
165
165
  : relativePath,
166
166
  ),
@@ -199,14 +199,14 @@ export function detectFramework(
199
199
  devDeps: Record<string, string>,
200
200
  ): string | null {
201
201
  const all = { ...deps, ...devDeps }
202
- if (all['next']) return 'Next.js'
203
- if (all['@remix-run/react'] || all['remix']) return 'Remix'
204
- if (all['gatsby']) return 'Gatsby'
205
- if (all['astro']) return 'Astro'
202
+ if (all.next) return 'Next.js'
203
+ if (all['@remix-run/react'] || all.remix) return 'Remix'
204
+ if (all.gatsby) return 'Gatsby'
205
+ if (all.astro) return 'Astro'
206
206
  if (all['@angular/core']) return 'Angular'
207
- if (all['vue']) return 'Vue'
208
- if (all['svelte']) return 'Svelte'
209
- if (all['react']) return 'React'
207
+ if (all.vue) return 'Vue'
208
+ if (all.svelte) return 'Svelte'
209
+ if (all.react) return 'React'
210
210
  return null
211
211
  }
212
212
 
@@ -219,13 +219,13 @@ export function detectCssStrategy(
219
219
  const all = { ...deps, ...devDeps }
220
220
  const strategies: string[] = []
221
221
 
222
- if (all['tailwindcss']) strategies.push('Tailwind')
222
+ if (all.tailwindcss) strategies.push('Tailwind')
223
223
  if (hasCssModules) strategies.push('CSS Modules')
224
224
  if (all['styled-components']) strategies.push('styled-components')
225
225
  if (all['@emotion/react'] || all['@emotion/styled'])
226
226
  strategies.push('Emotion')
227
- if (all['sass'] || all['node-sass']) strategies.push('Sass')
228
- if (all['less']) strategies.push('Less')
227
+ if (all.sass || all['node-sass']) strategies.push('Sass')
228
+ if (all.less) strategies.push('Less')
229
229
  if (all['@vanilla-extract/css']) strategies.push('Vanilla Extract')
230
230
 
231
231
  if (strategies.length === 0 && cssFiles.length > 0) {
@@ -264,7 +264,7 @@ function detectAssetDirs(resolved: string, assetDirs: Set<string>) {
264
264
  entry.isDirectory() &&
265
265
  ASSET_DIR_NAMES.has(entry.name.toLowerCase())
266
266
  ) {
267
- assetDirs.add('public/' + entry.name)
267
+ assetDirs.add(`public/${entry.name}`)
268
268
  }
269
269
  }
270
270
  if (entries.some((e) => e.isFile())) {
@@ -164,7 +164,7 @@ export function parseTailwindColorClasses(
164
164
 
165
165
  // Try to match each known prefix
166
166
  for (const [prefix, cssProperty] of Object.entries(PREFIX_TO_PROPERTY)) {
167
- const prefixWithDash = prefix + '-'
167
+ const prefixWithDash = `${prefix}-`
168
168
  if (!stripped.startsWith(prefixWithDash)) continue
169
169
 
170
170
  const suffix = stripped.slice(prefixWithDash.length)
@@ -34,7 +34,7 @@ function parseSingleTextShadow(str: string): TextShadowData | null {
34
34
  const trimmed = str.trim()
35
35
  if (!trimmed || trimmed === 'none') return null
36
36
 
37
- let working = trimmed
37
+ const working = trimmed
38
38
  let color = 'rgba(0,0,0,0.25)'
39
39
  let numericPart = working
40
40
 
package/src/lib/utils.ts CHANGED
@@ -8,8 +8,8 @@ import {
8
8
  * Handles vendor prefixes: webkitTextStroke → -webkit-text-stroke
9
9
  */
10
10
  export function camelToKebab(s: string): string {
11
- const k = s.replace(/[A-Z]/g, (c) => '-' + c.toLowerCase())
12
- if (/^(webkit|moz|ms)-/.test(k)) return '-' + k
11
+ const k = s.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`)
12
+ if (/^(webkit|moz|ms)-/.test(k)) return `-${k}`
13
13
  return k
14
14
  }
15
15
 
@@ -32,14 +32,14 @@ export function generateSelectorPath(element: Element): string {
32
32
  if (current.className && typeof current.className === 'string') {
33
33
  const classes = current.className.trim().split(/\s+/).filter(Boolean)
34
34
  if (classes.length > 0) {
35
- selector += '.' + classes.join('.')
35
+ selector += `.${classes.join('.')}`
36
36
  }
37
37
  }
38
38
 
39
39
  const parent = current.parentElement
40
40
  if (parent) {
41
41
  const siblings = Array.from(parent.children).filter(
42
- (child) => child.tagName === current!.tagName,
42
+ (child) => child.tagName === current?.tagName,
43
43
  )
44
44
  if (siblings.length > 1) {
45
45
  const index = siblings.indexOf(current) + 1
package/src/proxy.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { NextRequest, NextResponse } from 'next/server'
1
+ import { type NextRequest, NextResponse } from 'next/server'
2
2
 
3
3
  const PROXY_HEADER = 'x-dev-editor-target'
4
4
 
@@ -2,11 +2,11 @@ import type { StateCreator } from 'zustand'
2
2
  import type { TreeNode } from '@/types/tree'
3
3
 
4
4
  // Collect all node IDs that have children for full expansion
5
- function collectAllIds(node: TreeNode, ids: Set<string>) {
5
+ function _collectAllIds(node: TreeNode, ids: Set<string>) {
6
6
  if (node.children.length === 0) return
7
7
  ids.add(node.id)
8
8
  for (const child of node.children) {
9
- collectAllIds(child, ids)
9
+ _collectAllIds(child, ids)
10
10
  }
11
11
  }
12
12
 
@@ -1,104 +0,0 @@
1
- import * as pty from 'node-pty'
2
-
3
- const TERMINAL_PORT = Number(process.env.TERMINAL_PORT) || 4001
4
-
5
- interface WsData {
6
- pty: pty.IPty
7
- }
8
-
9
- Bun.serve<WsData>({
10
- port: TERMINAL_PORT,
11
-
12
- fetch(req, server) {
13
- const url = new URL(req.url)
14
-
15
- if (url.pathname === '/ws') {
16
- const ok = server.upgrade(req)
17
- if (!ok) return new Response('WebSocket upgrade failed', { status: 400 })
18
- return undefined
19
- }
20
-
21
- if (url.pathname === '/health') {
22
- return new Response('ok', {
23
- headers: { 'Access-Control-Allow-Origin': '*' },
24
- })
25
- }
26
-
27
- // CORS preflight
28
- if (req.method === 'OPTIONS') {
29
- return new Response(null, {
30
- status: 204,
31
- headers: {
32
- 'Access-Control-Allow-Origin': '*',
33
- 'Access-Control-Allow-Methods': 'GET',
34
- 'Access-Control-Allow-Headers': '*',
35
- },
36
- })
37
- }
38
-
39
- return new Response('Not found', { status: 404 })
40
- },
41
-
42
- websocket: {
43
- open(ws) {
44
- const shell = process.env.SHELL || '/bin/bash'
45
- const term = pty.spawn(shell, [], {
46
- name: 'xterm-256color',
47
- cols: 80,
48
- rows: 24,
49
- cwd: process.env.HOME || '/',
50
- env: process.env as Record<string, string>,
51
- })
52
-
53
- ws.data = { pty: term }
54
-
55
- term.onData((data: string) => {
56
- try {
57
- ws.send(data)
58
- } catch {
59
- // WebSocket already closed
60
- }
61
- })
62
-
63
- term.onExit(() => {
64
- try {
65
- ws.close()
66
- } catch {
67
- // Already closed
68
- }
69
- })
70
- },
71
-
72
- message(ws, message) {
73
- const { pty: term } = ws.data
74
- if (typeof message === 'string') {
75
- // Resize messages prefixed with \x01
76
- if (message.startsWith('\x01')) {
77
- try {
78
- const { cols, rows } = JSON.parse(message.slice(1))
79
- if (cols && rows) {
80
- term.resize(cols, rows)
81
- }
82
- } catch {
83
- // Invalid resize message, ignore
84
- }
85
- return
86
- }
87
- term.write(message)
88
- } else {
89
- // Binary data
90
- term.write(Buffer.from(message).toString())
91
- }
92
- },
93
-
94
- close(ws) {
95
- if (ws.data?.pty) {
96
- ws.data.pty.kill()
97
- }
98
- },
99
- },
100
- })
101
-
102
- console.log(
103
- `Terminal WebSocket server running on ws://localhost:${TERMINAL_PORT}/ws`,
104
- )
@@ -1,12 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "esnext",
5
- "moduleResolution": "bundler",
6
- "strict": true,
7
- "noEmit": true,
8
- "skipLibCheck": true,
9
- "types": ["bun-types"]
10
- },
11
- "include": ["src/server/**/*.ts"]
12
- }