@antigenic-oss/paint 0.1.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 (158) hide show
  1. package/LICENSE +178 -0
  2. package/NOTICE +4 -0
  3. package/README.md +180 -0
  4. package/bin/paint.js +266 -0
  5. package/next-env.d.ts +6 -0
  6. package/next.config.ts +19 -0
  7. package/package.json +81 -0
  8. package/postcss.config.mjs +8 -0
  9. package/public/dev-editor-inspector.js +1872 -0
  10. package/src/app/api/claude/analyze/route.ts +319 -0
  11. package/src/app/api/claude/apply/route.ts +185 -0
  12. package/src/app/api/claude/pick-folder/route.ts +64 -0
  13. package/src/app/api/claude/scan/route.ts +221 -0
  14. package/src/app/api/claude/status/route.ts +55 -0
  15. package/src/app/api/project/scan/route.ts +634 -0
  16. package/src/app/api/project-scan/css-variables/route.ts +238 -0
  17. package/src/app/api/project-scan/route.ts +40 -0
  18. package/src/app/api/project-scan/tailwind-config/route.ts +172 -0
  19. package/src/app/api/proxy/[[...path]]/route.ts +2400 -0
  20. package/src/app/docs/DocsClient.tsx +322 -0
  21. package/src/app/docs/layout.tsx +7 -0
  22. package/src/app/docs/page.tsx +855 -0
  23. package/src/app/globals.css +176 -0
  24. package/src/app/layout.tsx +19 -0
  25. package/src/app/page.tsx +46 -0
  26. package/src/bridge/api-handlers.ts +885 -0
  27. package/src/bridge/proxy-handler.ts +329 -0
  28. package/src/bridge/server.ts +113 -0
  29. package/src/components/BreakpointTabs.tsx +72 -0
  30. package/src/components/ChangeSummaryModal.tsx +267 -0
  31. package/src/components/ConnectModal.tsx +994 -0
  32. package/src/components/Editor.tsx +90 -0
  33. package/src/components/PageSelector.tsx +208 -0
  34. package/src/components/PreviewFrame.tsx +299 -0
  35. package/src/components/ProjectFolderBanner.tsx +91 -0
  36. package/src/components/ResponsiveToolbar.tsx +222 -0
  37. package/src/components/TargetSelector.tsx +243 -0
  38. package/src/components/TopBar.tsx +315 -0
  39. package/src/components/common/CollapsibleSection.tsx +36 -0
  40. package/src/components/common/ColorPicker.tsx +920 -0
  41. package/src/components/common/EditablePre.tsx +136 -0
  42. package/src/components/common/ErrorBoundary.tsx +65 -0
  43. package/src/components/common/ResizablePanel.tsx +83 -0
  44. package/src/components/common/ScanAnimation.tsx +76 -0
  45. package/src/components/common/ToastContainer.tsx +97 -0
  46. package/src/components/common/UnitInput.tsx +77 -0
  47. package/src/components/common/VariableColorPicker.tsx +622 -0
  48. package/src/components/left-panel/AddElementPanel.tsx +237 -0
  49. package/src/components/left-panel/ComponentsPanel.tsx +609 -0
  50. package/src/components/left-panel/IconSidebar.tsx +99 -0
  51. package/src/components/left-panel/LayerNode.tsx +874 -0
  52. package/src/components/left-panel/LayerSearch.tsx +23 -0
  53. package/src/components/left-panel/LayersPanel.tsx +52 -0
  54. package/src/components/left-panel/LeftPanel.tsx +122 -0
  55. package/src/components/left-panel/PagesPanel.tsx +114 -0
  56. package/src/components/left-panel/icons.tsx +162 -0
  57. package/src/components/left-panel/terminal/ScanOverlay.tsx +66 -0
  58. package/src/components/left-panel/terminal/TerminalPanel.tsx +217 -0
  59. package/src/components/right-panel/ElementLogBox.tsx +248 -0
  60. package/src/components/right-panel/PanelTabs.tsx +83 -0
  61. package/src/components/right-panel/RightPanel.tsx +41 -0
  62. package/src/components/right-panel/changes/AiScanResultPanel.tsx +285 -0
  63. package/src/components/right-panel/changes/ChangeEntry.tsx +59 -0
  64. package/src/components/right-panel/changes/ChangelogActions.tsx +105 -0
  65. package/src/components/right-panel/changes/ChangesPanel.tsx +1474 -0
  66. package/src/components/right-panel/claude/ApplyConfirmModal.tsx +376 -0
  67. package/src/components/right-panel/claude/ClaudeErrorState.tsx +125 -0
  68. package/src/components/right-panel/claude/ClaudeIntegrationPanel.tsx +482 -0
  69. package/src/components/right-panel/claude/ClaudeProgressIndicator.tsx +76 -0
  70. package/src/components/right-panel/claude/DiffCard.tsx +130 -0
  71. package/src/components/right-panel/claude/DiffViewer.tsx +54 -0
  72. package/src/components/right-panel/claude/ProjectRootSelector.tsx +275 -0
  73. package/src/components/right-panel/claude/ResultsSummary.tsx +119 -0
  74. package/src/components/right-panel/claude/SetupFlow.tsx +315 -0
  75. package/src/components/right-panel/console/ConsolePanel.tsx +209 -0
  76. package/src/components/right-panel/design/AppearanceSection.tsx +703 -0
  77. package/src/components/right-panel/design/BackgroundSection.tsx +516 -0
  78. package/src/components/right-panel/design/BorderSection.tsx +161 -0
  79. package/src/components/right-panel/design/CSSRawView.tsx +412 -0
  80. package/src/components/right-panel/design/DesignCSSTabToggle.tsx +51 -0
  81. package/src/components/right-panel/design/DesignPanel.tsx +275 -0
  82. package/src/components/right-panel/design/ElementBreadcrumb.tsx +51 -0
  83. package/src/components/right-panel/design/GradientEditor.tsx +726 -0
  84. package/src/components/right-panel/design/LayoutSection.tsx +1948 -0
  85. package/src/components/right-panel/design/PositionSection.tsx +865 -0
  86. package/src/components/right-panel/design/PropertiesSection.tsx +86 -0
  87. package/src/components/right-panel/design/SVGSection.tsx +361 -0
  88. package/src/components/right-panel/design/ShadowBlurSection.tsx +227 -0
  89. package/src/components/right-panel/design/SizeSection.tsx +183 -0
  90. package/src/components/right-panel/design/TextSection.tsx +719 -0
  91. package/src/components/right-panel/design/icons.tsx +948 -0
  92. package/src/components/right-panel/design/inputs/BoxModelPreview.tsx +467 -0
  93. package/src/components/right-panel/design/inputs/ColorInput.tsx +43 -0
  94. package/src/components/right-panel/design/inputs/CompactInput.tsx +333 -0
  95. package/src/components/right-panel/design/inputs/DraggableLabel.tsx +118 -0
  96. package/src/components/right-panel/design/inputs/IconToggleGroup.tsx +54 -0
  97. package/src/components/right-panel/design/inputs/LinkedInputPair.tsx +174 -0
  98. package/src/components/right-panel/design/inputs/SectionHeader.tsx +79 -0
  99. package/src/components/right-panel/variables/VariablesPanel.tsx +388 -0
  100. package/src/hooks/useBridge.ts +95 -0
  101. package/src/hooks/useChangeTracker.ts +563 -0
  102. package/src/hooks/useClaudeAPI.ts +118 -0
  103. package/src/hooks/useDOMTree.ts +25 -0
  104. package/src/hooks/useKeyboardShortcuts.ts +76 -0
  105. package/src/hooks/usePostMessage.ts +589 -0
  106. package/src/hooks/useProjectScan.ts +204 -0
  107. package/src/hooks/useResizable.ts +20 -0
  108. package/src/hooks/useSelectedElement.ts +51 -0
  109. package/src/hooks/useTargetUrl.ts +81 -0
  110. package/src/inspector/DOMTraverser.ts +71 -0
  111. package/src/inspector/ElementSelector.ts +23 -0
  112. package/src/inspector/HoverHighlighter.ts +54 -0
  113. package/src/inspector/SelectionHighlighter.ts +27 -0
  114. package/src/inspector/StyleExtractor.ts +19 -0
  115. package/src/inspector/inspector.ts +17 -0
  116. package/src/inspector/messaging.ts +30 -0
  117. package/src/lib/apiBase.ts +15 -0
  118. package/src/lib/classifyElement.ts +430 -0
  119. package/src/lib/claude-bin.ts +197 -0
  120. package/src/lib/claude-stream.ts +158 -0
  121. package/src/lib/clientProjectScanner.ts +344 -0
  122. package/src/lib/componentMatcher.ts +156 -0
  123. package/src/lib/constants.ts +573 -0
  124. package/src/lib/cssVariableUtils.ts +409 -0
  125. package/src/lib/diffParser.ts +206 -0
  126. package/src/lib/folderPicker.ts +84 -0
  127. package/src/lib/gradientParser.ts +160 -0
  128. package/src/lib/projectScanner.ts +355 -0
  129. package/src/lib/promptBuilder.ts +402 -0
  130. package/src/lib/shadowParser.ts +124 -0
  131. package/src/lib/tailwindClassParser.ts +248 -0
  132. package/src/lib/textShadowUtils.ts +106 -0
  133. package/src/lib/utils.ts +299 -0
  134. package/src/lib/validatePath.ts +40 -0
  135. package/src/proxy.ts +92 -0
  136. package/src/server/terminal-server.ts +104 -0
  137. package/src/store/changeSlice.ts +288 -0
  138. package/src/store/claudeSlice.ts +222 -0
  139. package/src/store/componentSlice.ts +90 -0
  140. package/src/store/consoleSlice.ts +51 -0
  141. package/src/store/cssVariableSlice.ts +94 -0
  142. package/src/store/elementSlice.ts +78 -0
  143. package/src/store/index.ts +35 -0
  144. package/src/store/terminalSlice.ts +30 -0
  145. package/src/store/treeSlice.ts +69 -0
  146. package/src/store/uiSlice.ts +327 -0
  147. package/src/types/changelog.ts +49 -0
  148. package/src/types/claude.ts +131 -0
  149. package/src/types/component.ts +49 -0
  150. package/src/types/cssVariables.ts +18 -0
  151. package/src/types/element.ts +21 -0
  152. package/src/types/file-system-access.d.ts +27 -0
  153. package/src/types/gradient.ts +12 -0
  154. package/src/types/messages.ts +392 -0
  155. package/src/types/shadow.ts +8 -0
  156. package/src/types/tree.ts +9 -0
  157. package/tsconfig.json +42 -0
  158. package/tsconfig.server.json +12 -0
@@ -0,0 +1,176 @@
1
+ @import "tailwindcss";
2
+
3
+ :root {
4
+ --bg-primary: #1e1e1e;
5
+ --bg-secondary: #252526;
6
+ --bg-tertiary: #2d2d30;
7
+ --bg-hover: #3c3c3c;
8
+ --bg-active: #37373d;
9
+
10
+ --text-primary: #e0e0e0;
11
+ --text-secondary: #a0a0a0;
12
+ --text-muted: #6a6a6a;
13
+
14
+ --accent: #4a9eff;
15
+ --accent-hover: #5aafff;
16
+ --accent-bg: rgba(74, 158, 255, 0.1);
17
+
18
+ --border: #3c3c3c;
19
+ --border-hover: #555555;
20
+
21
+ --success: #4ec9b0;
22
+ --warning: #dcdcaa;
23
+ --error: #f44747;
24
+
25
+ --highlight-hover: rgba(74, 158, 255, 0.2);
26
+ --highlight-selected: rgba(74, 158, 255, 0.35);
27
+
28
+ --panel-min-left: 180px;
29
+ --panel-max-left: 400px;
30
+ --panel-min-right: 240px;
31
+ --panel-max-right: 500px;
32
+ }
33
+
34
+ html,
35
+ body {
36
+ margin: 0;
37
+ padding: 0;
38
+ height: 100%;
39
+ background-color: var(--bg-primary);
40
+ color: var(--text-primary);
41
+ font-family:
42
+ -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
43
+ Arial, sans-serif;
44
+ font-size: 13px;
45
+ line-height: 1.4;
46
+ -webkit-font-smoothing: antialiased;
47
+ -moz-osx-font-smoothing: grayscale;
48
+ }
49
+
50
+ * {
51
+ box-sizing: border-box;
52
+ }
53
+
54
+ #__next {
55
+ height: 100%;
56
+ }
57
+
58
+ ::-webkit-scrollbar {
59
+ width: 8px;
60
+ height: 8px;
61
+ }
62
+
63
+ ::-webkit-scrollbar-track {
64
+ background: transparent;
65
+ }
66
+
67
+ ::-webkit-scrollbar-thumb {
68
+ background: var(--bg-hover);
69
+ border-radius: 4px;
70
+ }
71
+
72
+ ::-webkit-scrollbar-thumb:hover {
73
+ background: var(--border-hover);
74
+ }
75
+
76
+ ::selection {
77
+ background-color: var(--highlight-selected);
78
+ }
79
+
80
+ input,
81
+ select,
82
+ button {
83
+ font-family: inherit;
84
+ font-size: inherit;
85
+ }
86
+
87
+ input[type="text"],
88
+ input[type="number"],
89
+ input[type="url"] {
90
+ background: var(--bg-tertiary);
91
+ border: 1px solid var(--border);
92
+ color: var(--text-primary);
93
+ border-radius: 4px;
94
+ padding: 4px 8px;
95
+ outline: none;
96
+ transition: border-color 0.15s;
97
+ }
98
+
99
+ input[type="text"]:focus,
100
+ input[type="number"]:focus,
101
+ input[type="url"]:focus {
102
+ border-color: var(--accent);
103
+ }
104
+
105
+ /* Scan overlay animations */
106
+ @keyframes scan-sweep {
107
+ 0% {
108
+ top: 0%;
109
+ opacity: 0;
110
+ }
111
+ 10% {
112
+ opacity: 1;
113
+ }
114
+ 90% {
115
+ opacity: 1;
116
+ }
117
+ 100% {
118
+ top: 100%;
119
+ opacity: 0;
120
+ }
121
+ }
122
+
123
+ @keyframes scan-pulse {
124
+ 0%,
125
+ 100% {
126
+ opacity: 0.3;
127
+ transform: scale(1);
128
+ }
129
+ 50% {
130
+ opacity: 0.8;
131
+ transform: scale(1.05);
132
+ }
133
+ }
134
+
135
+ @keyframes scan-dot {
136
+ 0%,
137
+ 80%,
138
+ 100% {
139
+ opacity: 0.2;
140
+ transform: scale(0.8);
141
+ }
142
+ 40% {
143
+ opacity: 1;
144
+ transform: scale(1);
145
+ }
146
+ }
147
+
148
+ @keyframes scan-ring {
149
+ 0% {
150
+ transform: scale(0.3);
151
+ opacity: 0.6;
152
+ }
153
+ 100% {
154
+ transform: scale(1.8);
155
+ opacity: 0;
156
+ }
157
+ }
158
+
159
+ @keyframes scan-glow {
160
+ 0%,
161
+ 100% {
162
+ box-shadow: 0 0 8px rgba(74, 158, 255, 0.3);
163
+ }
164
+ 50% {
165
+ box-shadow: 0 0 20px rgba(74, 158, 255, 0.6);
166
+ }
167
+ }
168
+
169
+ @keyframes spin {
170
+ from {
171
+ transform: rotate(0deg);
172
+ }
173
+ to {
174
+ transform: rotate(360deg);
175
+ }
176
+ }
@@ -0,0 +1,19 @@
1
+ import type { Metadata } from 'next'
2
+ import './globals.css'
3
+
4
+ export const metadata: Metadata = {
5
+ title: 'pAInt',
6
+ description: 'Visual design editor for localhost projects',
7
+ }
8
+
9
+ export default function RootLayout({
10
+ children,
11
+ }: {
12
+ children: React.ReactNode
13
+ }) {
14
+ return (
15
+ <html lang="en" className="dark">
16
+ <body>{children}</body>
17
+ </html>
18
+ )
19
+ }
@@ -0,0 +1,46 @@
1
+ 'use client'
2
+
3
+ import { useEffect, useState } from 'react'
4
+ import { Editor } from '@/components/Editor'
5
+ import { useEditorStore } from '@/store'
6
+
7
+ export default function Home() {
8
+ const loadPersistedUI = useEditorStore((s) => s.loadPersistedUI)
9
+ const loadPersistedClaude = useEditorStore((s) => s.loadPersistedClaude)
10
+
11
+ // Safety net: if pAInt's own page loads inside an iframe,
12
+ // it means the proxy's navigation blocker failed and the iframe
13
+ // escaped to localhost:4000. Notify the parent editor so it can recover.
14
+ const [isRecursiveEmbed, setIsRecursiveEmbed] = useState(false)
15
+
16
+ useEffect(() => {
17
+ if (window.self !== window.top) {
18
+ setIsRecursiveEmbed(true)
19
+ try {
20
+ window.parent.postMessage({ type: 'RECURSIVE_EMBED_DETECTED' }, '*')
21
+ } catch (e) {
22
+ /* cross-origin */
23
+ }
24
+ return
25
+ }
26
+
27
+ loadPersistedUI()
28
+ loadPersistedClaude()
29
+
30
+ // Suppress HMR errors caused by proxied routes leaking into the
31
+ // editor's route tree (e.g. "unrecognized HMR message").
32
+ const suppressHmrErrors = (e: PromiseRejectionEvent) => {
33
+ const msg = e.reason?.message || String(e.reason || '')
34
+ if (msg.includes('unrecognized HMR message') || msg.includes('HMR')) {
35
+ e.preventDefault()
36
+ }
37
+ }
38
+ window.addEventListener('unhandledrejection', suppressHmrErrors)
39
+ return () =>
40
+ window.removeEventListener('unhandledrejection', suppressHmrErrors)
41
+ }, [loadPersistedUI, loadPersistedClaude])
42
+
43
+ if (isRecursiveEmbed) return null
44
+
45
+ return <Editor />
46
+ }