@aprovan/patchwork 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 (225) hide show
  1. package/.eslintrc.json +22 -0
  2. package/.github/workflows/publish.yml +41 -0
  3. package/.prettierignore +17 -0
  4. package/LICENSE +373 -0
  5. package/README.md +15 -0
  6. package/apps/chat/.utcp_config.json +14 -0
  7. package/apps/chat/.working/widgets/27060b91-a2a5-4272-b243-6eb904bd4070/main.tsx +107 -0
  8. package/apps/chat/index.html +17 -0
  9. package/apps/chat/node_modules/.bin/autoprefixer +17 -0
  10. package/apps/chat/node_modules/.bin/browserslist +17 -0
  11. package/apps/chat/node_modules/.bin/conc +17 -0
  12. package/apps/chat/node_modules/.bin/concurrently +17 -0
  13. package/apps/chat/node_modules/.bin/copilot-proxy +17 -0
  14. package/apps/chat/node_modules/.bin/jiti +17 -0
  15. package/apps/chat/node_modules/.bin/tailwind +17 -0
  16. package/apps/chat/node_modules/.bin/tailwindcss +17 -0
  17. package/apps/chat/node_modules/.bin/tsc +17 -0
  18. package/apps/chat/node_modules/.bin/tsserver +17 -0
  19. package/apps/chat/node_modules/.bin/tsx +17 -0
  20. package/apps/chat/node_modules/.bin/vite +17 -0
  21. package/apps/chat/package.json +55 -0
  22. package/apps/chat/postcss.config.js +6 -0
  23. package/apps/chat/src/App.tsx +7 -0
  24. package/apps/chat/src/components/ui/avatar.tsx +48 -0
  25. package/apps/chat/src/components/ui/badge.tsx +36 -0
  26. package/apps/chat/src/components/ui/button.tsx +56 -0
  27. package/apps/chat/src/components/ui/card.tsx +86 -0
  28. package/apps/chat/src/components/ui/collapsible.tsx +9 -0
  29. package/apps/chat/src/components/ui/dialog.tsx +60 -0
  30. package/apps/chat/src/components/ui/input.tsx +25 -0
  31. package/apps/chat/src/components/ui/scroll-area.tsx +46 -0
  32. package/apps/chat/src/index.css +190 -0
  33. package/apps/chat/src/lib/utils.ts +6 -0
  34. package/apps/chat/src/main.tsx +10 -0
  35. package/apps/chat/src/pages/ChatPage.tsx +460 -0
  36. package/apps/chat/tailwind.config.js +71 -0
  37. package/apps/chat/tsconfig.json +25 -0
  38. package/apps/chat/vite.config.ts +26 -0
  39. package/package.json +35 -0
  40. package/packages/bobbin/node_modules/.bin/esbuild +14 -0
  41. package/packages/bobbin/node_modules/.bin/jiti +17 -0
  42. package/packages/bobbin/node_modules/.bin/tsc +17 -0
  43. package/packages/bobbin/node_modules/.bin/tsserver +17 -0
  44. package/packages/bobbin/node_modules/.bin/tsup +17 -0
  45. package/packages/bobbin/node_modules/.bin/tsup-node +17 -0
  46. package/packages/bobbin/node_modules/.bin/tsx +17 -0
  47. package/packages/bobbin/package.json +30 -0
  48. package/packages/bobbin/src/Bobbin.tsx +89 -0
  49. package/packages/bobbin/src/components/EditPanel/EditPanel.tsx +376 -0
  50. package/packages/bobbin/src/components/EditPanel/controls/ColorPicker.tsx +138 -0
  51. package/packages/bobbin/src/components/EditPanel/controls/QuickSelectDropdown.tsx +142 -0
  52. package/packages/bobbin/src/components/EditPanel/controls/SliderInput.tsx +94 -0
  53. package/packages/bobbin/src/components/EditPanel/controls/SpacingControl.tsx +285 -0
  54. package/packages/bobbin/src/components/EditPanel/controls/ToggleGroup.tsx +37 -0
  55. package/packages/bobbin/src/components/EditPanel/controls/TokenDropdown.tsx +33 -0
  56. package/packages/bobbin/src/components/EditPanel/sections/AnnotationSection.tsx +136 -0
  57. package/packages/bobbin/src/components/EditPanel/sections/BackgroundSection.tsx +79 -0
  58. package/packages/bobbin/src/components/EditPanel/sections/EffectsSection.tsx +85 -0
  59. package/packages/bobbin/src/components/EditPanel/sections/LayoutSection.tsx +224 -0
  60. package/packages/bobbin/src/components/EditPanel/sections/SectionWrapper.tsx +57 -0
  61. package/packages/bobbin/src/components/EditPanel/sections/SizeSection.tsx +166 -0
  62. package/packages/bobbin/src/components/EditPanel/sections/SpacingSection.tsx +69 -0
  63. package/packages/bobbin/src/components/EditPanel/sections/TypographySection.tsx +148 -0
  64. package/packages/bobbin/src/components/Inspector/Inspector.tsx +221 -0
  65. package/packages/bobbin/src/components/Overlay/ControlHandles.tsx +572 -0
  66. package/packages/bobbin/src/components/Overlay/MarginPaddingOverlay.tsx +229 -0
  67. package/packages/bobbin/src/components/Overlay/SelectionOverlay.tsx +73 -0
  68. package/packages/bobbin/src/components/Pill/Pill.tsx +155 -0
  69. package/packages/bobbin/src/components/ThemeToggle/ThemeToggle.tsx +72 -0
  70. package/packages/bobbin/src/core/changeSerializer.ts +139 -0
  71. package/packages/bobbin/src/core/useBobbin.ts +399 -0
  72. package/packages/bobbin/src/core/useChangeTracker.ts +186 -0
  73. package/packages/bobbin/src/core/useClipboard.ts +21 -0
  74. package/packages/bobbin/src/core/useElementSelection.ts +146 -0
  75. package/packages/bobbin/src/index.ts +46 -0
  76. package/packages/bobbin/src/tokens/borders.ts +19 -0
  77. package/packages/bobbin/src/tokens/colors.ts +150 -0
  78. package/packages/bobbin/src/tokens/index.ts +37 -0
  79. package/packages/bobbin/src/tokens/shadows.ts +10 -0
  80. package/packages/bobbin/src/tokens/spacing.ts +37 -0
  81. package/packages/bobbin/src/tokens/typography.ts +51 -0
  82. package/packages/bobbin/src/types.ts +157 -0
  83. package/packages/bobbin/src/utils/animation.ts +40 -0
  84. package/packages/bobbin/src/utils/dom.ts +36 -0
  85. package/packages/bobbin/src/utils/selectors.ts +76 -0
  86. package/packages/bobbin/tsconfig.json +10 -0
  87. package/packages/bobbin/tsup.config.ts +10 -0
  88. package/packages/compiler/node_modules/.bin/esbuild +17 -0
  89. package/packages/compiler/node_modules/.bin/jiti +17 -0
  90. package/packages/compiler/node_modules/.bin/tsc +17 -0
  91. package/packages/compiler/node_modules/.bin/tsserver +17 -0
  92. package/packages/compiler/node_modules/.bin/tsup +17 -0
  93. package/packages/compiler/node_modules/.bin/tsup-node +17 -0
  94. package/packages/compiler/node_modules/.bin/tsx +17 -0
  95. package/packages/compiler/package.json +38 -0
  96. package/packages/compiler/src/compiler.ts +258 -0
  97. package/packages/compiler/src/images/index.ts +13 -0
  98. package/packages/compiler/src/images/loader.ts +234 -0
  99. package/packages/compiler/src/images/registry.ts +112 -0
  100. package/packages/compiler/src/index.ts +141 -0
  101. package/packages/compiler/src/mount/bridge.ts +399 -0
  102. package/packages/compiler/src/mount/embedded.ts +306 -0
  103. package/packages/compiler/src/mount/iframe.ts +433 -0
  104. package/packages/compiler/src/mount/index.ts +18 -0
  105. package/packages/compiler/src/schemas.ts +169 -0
  106. package/packages/compiler/src/transforms/cdn.ts +411 -0
  107. package/packages/compiler/src/transforms/index.ts +4 -0
  108. package/packages/compiler/src/transforms/vfs.ts +138 -0
  109. package/packages/compiler/src/types.ts +233 -0
  110. package/packages/compiler/src/vfs/backends/indexeddb.ts +66 -0
  111. package/packages/compiler/src/vfs/backends/local-fs.ts +41 -0
  112. package/packages/compiler/src/vfs/backends/s3.ts +60 -0
  113. package/packages/compiler/src/vfs/index.ts +11 -0
  114. package/packages/compiler/src/vfs/project.ts +56 -0
  115. package/packages/compiler/src/vfs/store.ts +53 -0
  116. package/packages/compiler/src/vfs/types.ts +20 -0
  117. package/packages/compiler/tsconfig.json +8 -0
  118. package/packages/compiler/tsup.config.ts +14 -0
  119. package/packages/editor/node_modules/.bin/jiti +17 -0
  120. package/packages/editor/node_modules/.bin/tsc +17 -0
  121. package/packages/editor/node_modules/.bin/tsserver +17 -0
  122. package/packages/editor/node_modules/.bin/tsup +17 -0
  123. package/packages/editor/node_modules/.bin/tsup-node +17 -0
  124. package/packages/editor/node_modules/.bin/tsx +17 -0
  125. package/packages/editor/package.json +45 -0
  126. package/packages/editor/src/components/CodeBlockExtension.tsx +190 -0
  127. package/packages/editor/src/components/CodePreview.tsx +344 -0
  128. package/packages/editor/src/components/MarkdownEditor.tsx +270 -0
  129. package/packages/editor/src/components/ServicesInspector.tsx +118 -0
  130. package/packages/editor/src/components/edit/EditHistory.tsx +89 -0
  131. package/packages/editor/src/components/edit/EditModal.tsx +236 -0
  132. package/packages/editor/src/components/edit/FileTree.tsx +144 -0
  133. package/packages/editor/src/components/edit/api.ts +100 -0
  134. package/packages/editor/src/components/edit/index.ts +6 -0
  135. package/packages/editor/src/components/edit/types.ts +53 -0
  136. package/packages/editor/src/components/edit/useEditSession.ts +164 -0
  137. package/packages/editor/src/components/index.ts +5 -0
  138. package/packages/editor/src/index.ts +72 -0
  139. package/packages/editor/src/lib/code-extractor.ts +210 -0
  140. package/packages/editor/src/lib/diff.ts +308 -0
  141. package/packages/editor/src/lib/index.ts +4 -0
  142. package/packages/editor/src/lib/utils.ts +6 -0
  143. package/packages/editor/src/lib/vfs.ts +106 -0
  144. package/packages/editor/tsconfig.json +10 -0
  145. package/packages/editor/tsup.config.ts +10 -0
  146. package/packages/images/ink/node_modules/.bin/jiti +17 -0
  147. package/packages/images/ink/node_modules/.bin/tsc +17 -0
  148. package/packages/images/ink/node_modules/.bin/tsserver +17 -0
  149. package/packages/images/ink/node_modules/.bin/tsup +17 -0
  150. package/packages/images/ink/node_modules/.bin/tsup-node +17 -0
  151. package/packages/images/ink/node_modules/.bin/tsx +17 -0
  152. package/packages/images/ink/package.json +53 -0
  153. package/packages/images/ink/src/index.ts +48 -0
  154. package/packages/images/ink/src/runner.ts +331 -0
  155. package/packages/images/ink/src/setup.ts +123 -0
  156. package/packages/images/ink/tsconfig.json +10 -0
  157. package/packages/images/ink/tsup.config.ts +11 -0
  158. package/packages/images/shadcn/node_modules/.bin/jiti +17 -0
  159. package/packages/images/shadcn/node_modules/.bin/tsc +17 -0
  160. package/packages/images/shadcn/node_modules/.bin/tsserver +17 -0
  161. package/packages/images/shadcn/node_modules/.bin/tsup +17 -0
  162. package/packages/images/shadcn/node_modules/.bin/tsup-node +17 -0
  163. package/packages/images/shadcn/node_modules/.bin/tsx +17 -0
  164. package/packages/images/shadcn/package.json +82 -0
  165. package/packages/images/shadcn/src/html.ts +341 -0
  166. package/packages/images/shadcn/src/index.ts +37 -0
  167. package/packages/images/shadcn/src/setup.ts +287 -0
  168. package/packages/images/shadcn/tsconfig.json +9 -0
  169. package/packages/images/shadcn/tsup.config.ts +13 -0
  170. package/packages/images/vanilla/node_modules/.bin/jiti +17 -0
  171. package/packages/images/vanilla/node_modules/.bin/tsc +17 -0
  172. package/packages/images/vanilla/node_modules/.bin/tsserver +17 -0
  173. package/packages/images/vanilla/node_modules/.bin/tsup +17 -0
  174. package/packages/images/vanilla/node_modules/.bin/tsup-node +17 -0
  175. package/packages/images/vanilla/node_modules/.bin/tsx +17 -0
  176. package/packages/images/vanilla/package.json +35 -0
  177. package/packages/images/vanilla/src/index.ts +7 -0
  178. package/packages/images/vanilla/src/setup.ts +6 -0
  179. package/packages/images/vanilla/tsconfig.json +9 -0
  180. package/packages/images/vanilla/tsup.config.ts +10 -0
  181. package/packages/patchwork/node_modules/.bin/jiti +17 -0
  182. package/packages/patchwork/node_modules/.bin/tsc +17 -0
  183. package/packages/patchwork/node_modules/.bin/tsserver +17 -0
  184. package/packages/patchwork/node_modules/.bin/tsup +17 -0
  185. package/packages/patchwork/node_modules/.bin/tsup-node +17 -0
  186. package/packages/patchwork/node_modules/.bin/tsx +17 -0
  187. package/packages/patchwork/package.json +27 -0
  188. package/packages/patchwork/src/index.ts +15 -0
  189. package/packages/patchwork/src/services/index.ts +11 -0
  190. package/packages/patchwork/src/services/proxy.ts +213 -0
  191. package/packages/patchwork/src/services/types.ts +28 -0
  192. package/packages/patchwork/src/types.ts +116 -0
  193. package/packages/patchwork/tsconfig.json +8 -0
  194. package/packages/patchwork/tsup.config.ts +14 -0
  195. package/packages/stitchery/node_modules/.bin/jiti +17 -0
  196. package/packages/stitchery/node_modules/.bin/tsc +17 -0
  197. package/packages/stitchery/node_modules/.bin/tsserver +17 -0
  198. package/packages/stitchery/node_modules/.bin/tsup +17 -0
  199. package/packages/stitchery/node_modules/.bin/tsup-node +17 -0
  200. package/packages/stitchery/node_modules/.bin/tsx +17 -0
  201. package/packages/stitchery/package.json +40 -0
  202. package/packages/stitchery/src/cli.ts +116 -0
  203. package/packages/stitchery/src/index.ts +16 -0
  204. package/packages/stitchery/src/prompts.ts +326 -0
  205. package/packages/stitchery/src/server/index.ts +365 -0
  206. package/packages/stitchery/src/server/local-packages.ts +91 -0
  207. package/packages/stitchery/src/server/routes.ts +122 -0
  208. package/packages/stitchery/src/server/services.ts +382 -0
  209. package/packages/stitchery/src/server/vfs-routes.ts +142 -0
  210. package/packages/stitchery/src/types.ts +59 -0
  211. package/packages/stitchery/tsconfig.json +13 -0
  212. package/packages/stitchery/tsup.config.ts +15 -0
  213. package/packages/utcp/node_modules/.bin/jiti +17 -0
  214. package/packages/utcp/node_modules/.bin/tsc +17 -0
  215. package/packages/utcp/node_modules/.bin/tsserver +17 -0
  216. package/packages/utcp/node_modules/.bin/tsup +17 -0
  217. package/packages/utcp/node_modules/.bin/tsup-node +17 -0
  218. package/packages/utcp/node_modules/.bin/tsx +17 -0
  219. package/packages/utcp/package.json +38 -0
  220. package/packages/utcp/src/index.ts +153 -0
  221. package/packages/utcp/tsconfig.json +8 -0
  222. package/packages/utcp/tsup.config.ts +12 -0
  223. package/pnpm-workspace.yaml +3 -0
  224. package/tsconfig.json +18 -0
  225. package/turbo.json +23 -0
@@ -0,0 +1,123 @@
1
+ /**
2
+ * @aprovan/patchwork-image-ink
3
+ *
4
+ * Setup function for the Ink terminal UI image.
5
+ * Handles terminal environment configuration for CLI widgets.
6
+ */
7
+
8
+ import type { WriteStream } from 'node:tty';
9
+
10
+ export interface SetupOptions {
11
+ /** Output stream (default: process.stdout) */
12
+ stdout?: WriteStream;
13
+ /** Input stream (default: process.stdin) */
14
+ stdin?: NodeJS.ReadStream;
15
+ /** Enable color support detection override */
16
+ colorMode?: 'detect' | 'ansi' | 'ansi256' | 'truecolor' | 'none';
17
+ /** Enable debug mode (default: false) */
18
+ debug?: boolean;
19
+ }
20
+
21
+ export interface InkEnvironment {
22
+ stdout: WriteStream;
23
+ stdin: NodeJS.ReadStream;
24
+ colorSupport: 'none' | 'ansi' | 'ansi256' | 'truecolor';
25
+ isInteractive: boolean;
26
+ columns: number;
27
+ rows: number;
28
+ }
29
+
30
+ /**
31
+ * Detect terminal color support
32
+ */
33
+ function detectColorSupport(
34
+ stdout: WriteStream,
35
+ ): 'none' | 'ansi' | 'ansi256' | 'truecolor' {
36
+ // Check for NO_COLOR environment variable
37
+ if (process.env['NO_COLOR'] !== undefined) {
38
+ return 'none';
39
+ }
40
+
41
+ // Check for FORCE_COLOR
42
+ const forceColor = process.env['FORCE_COLOR'];
43
+ if (forceColor !== undefined) {
44
+ if (forceColor === '0') return 'none';
45
+ if (forceColor === '1') return 'ansi';
46
+ if (forceColor === '2') return 'ansi256';
47
+ if (forceColor === '3') return 'truecolor';
48
+ }
49
+
50
+ // Check COLORTERM for true color
51
+ if (
52
+ process.env['COLORTERM'] === 'truecolor' ||
53
+ process.env['COLORTERM'] === '24bit'
54
+ ) {
55
+ return 'truecolor';
56
+ }
57
+
58
+ // Check terminal capabilities
59
+ if (!stdout.isTTY) {
60
+ return 'none';
61
+ }
62
+
63
+ // Check TERM for 256 color support
64
+ const term = process.env['TERM'] || '';
65
+ if (term.includes('256color') || term.includes('256')) {
66
+ return 'ansi256';
67
+ }
68
+
69
+ // Default to basic ANSI if TTY
70
+ return 'ansi';
71
+ }
72
+
73
+ /**
74
+ * Setup the Ink terminal UI image runtime environment
75
+ *
76
+ * @param options - Optional configuration
77
+ * @returns Environment configuration for Ink
78
+ */
79
+ export function setup(options: SetupOptions = {}): InkEnvironment {
80
+ const {
81
+ stdout = process.stdout as WriteStream,
82
+ stdin = process.stdin,
83
+ colorMode = 'detect',
84
+ debug = false,
85
+ } = options;
86
+
87
+ // Detect or use specified color mode
88
+ let colorSupport: 'none' | 'ansi' | 'ansi256' | 'truecolor';
89
+ if (colorMode === 'detect') {
90
+ colorSupport = detectColorSupport(stdout);
91
+ } else {
92
+ colorSupport = colorMode;
93
+ }
94
+
95
+ // Get terminal dimensions
96
+ const columns = stdout.columns || 80;
97
+ const rows = stdout.rows || 24;
98
+
99
+ // Check if interactive
100
+ const isInteractive = stdin.isTTY ?? false;
101
+
102
+ if (debug) {
103
+ console.error(`[patchwork-ink] Color support: ${colorSupport}`);
104
+ console.error(`[patchwork-ink] Terminal size: ${columns}x${rows}`);
105
+ console.error(`[patchwork-ink] Interactive: ${isInteractive}`);
106
+ }
107
+
108
+ return {
109
+ stdout,
110
+ stdin,
111
+ colorSupport,
112
+ isInteractive,
113
+ columns,
114
+ rows,
115
+ };
116
+ }
117
+
118
+ /**
119
+ * Cleanup - no-op for CLI but provided for API consistency
120
+ */
121
+ export function cleanup(): void {
122
+ // No cleanup needed for terminal
123
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "rootDir": "src",
6
+ "lib": ["ES2020"],
7
+ "moduleResolution": "bundler"
8
+ },
9
+ "include": ["src/**/*"]
10
+ }
@@ -0,0 +1,11 @@
1
+ import { defineConfig } from 'tsup';
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.ts', 'src/setup.ts', 'src/runner.ts'],
5
+ format: ['esm'],
6
+ dts: true,
7
+ sourcemap: true,
8
+ clean: true,
9
+ target: 'node20',
10
+ external: ['react', 'ink', 'chalk'],
11
+ });
@@ -0,0 +1,17 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
6
+ esac
7
+
8
+ if [ -z "$NODE_PATH" ]; then
9
+ export NODE_PATH="/home/runner/work/patchwork/patchwork/node_modules/.pnpm/jiti@1.21.7/node_modules/jiti/bin/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/jiti@1.21.7/node_modules/jiti/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/jiti@1.21.7/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/node_modules"
10
+ else
11
+ export NODE_PATH="/home/runner/work/patchwork/patchwork/node_modules/.pnpm/jiti@1.21.7/node_modules/jiti/bin/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/jiti@1.21.7/node_modules/jiti/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/jiti@1.21.7/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/node_modules:$NODE_PATH"
12
+ fi
13
+ if [ -x "$basedir/node" ]; then
14
+ exec "$basedir/node" "$basedir/../../../../../node_modules/.pnpm/jiti@1.21.7/node_modules/jiti/bin/jiti.js" "$@"
15
+ else
16
+ exec node "$basedir/../../../../../node_modules/.pnpm/jiti@1.21.7/node_modules/jiti/bin/jiti.js" "$@"
17
+ fi
@@ -0,0 +1,17 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
6
+ esac
7
+
8
+ if [ -z "$NODE_PATH" ]; then
9
+ export NODE_PATH="/home/runner/work/patchwork/patchwork/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/node_modules"
10
+ else
11
+ export NODE_PATH="/home/runner/work/patchwork/patchwork/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/node_modules:$NODE_PATH"
12
+ fi
13
+ if [ -x "$basedir/node" ]; then
14
+ exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@"
15
+ else
16
+ exec node "$basedir/../typescript/bin/tsc" "$@"
17
+ fi
@@ -0,0 +1,17 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
6
+ esac
7
+
8
+ if [ -z "$NODE_PATH" ]; then
9
+ export NODE_PATH="/home/runner/work/patchwork/patchwork/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/node_modules"
10
+ else
11
+ export NODE_PATH="/home/runner/work/patchwork/patchwork/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/node_modules:$NODE_PATH"
12
+ fi
13
+ if [ -x "$basedir/node" ]; then
14
+ exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@"
15
+ else
16
+ exec node "$basedir/../typescript/bin/tsserver" "$@"
17
+ fi
@@ -0,0 +1,17 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
6
+ esac
7
+
8
+ if [ -z "$NODE_PATH" ]; then
9
+ export NODE_PATH="/home/runner/work/patchwork/patchwork/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/dist/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/node_modules"
10
+ else
11
+ export NODE_PATH="/home/runner/work/patchwork/patchwork/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/dist/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/node_modules:$NODE_PATH"
12
+ fi
13
+ if [ -x "$basedir/node" ]; then
14
+ exec "$basedir/node" "$basedir/../tsup/dist/cli-default.js" "$@"
15
+ else
16
+ exec node "$basedir/../tsup/dist/cli-default.js" "$@"
17
+ fi
@@ -0,0 +1,17 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
6
+ esac
7
+
8
+ if [ -z "$NODE_PATH" ]; then
9
+ export NODE_PATH="/home/runner/work/patchwork/patchwork/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/dist/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/node_modules"
10
+ else
11
+ export NODE_PATH="/home/runner/work/patchwork/patchwork/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/dist/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/node_modules:$NODE_PATH"
12
+ fi
13
+ if [ -x "$basedir/node" ]; then
14
+ exec "$basedir/node" "$basedir/../tsup/dist/cli-node.js" "$@"
15
+ else
16
+ exec node "$basedir/../tsup/dist/cli-node.js" "$@"
17
+ fi
@@ -0,0 +1,17 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
6
+ esac
7
+
8
+ if [ -z "$NODE_PATH" ]; then
9
+ export NODE_PATH="/home/runner/work/patchwork/patchwork/node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/dist/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/tsx@4.21.0/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/node_modules"
10
+ else
11
+ export NODE_PATH="/home/runner/work/patchwork/patchwork/node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/dist/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/tsx@4.21.0/node_modules:/home/runner/work/patchwork/patchwork/node_modules/.pnpm/node_modules:$NODE_PATH"
12
+ fi
13
+ if [ -x "$basedir/node" ]; then
14
+ exec "$basedir/node" "$basedir/../../../../../node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/dist/cli.mjs" "$@"
15
+ else
16
+ exec node "$basedir/../../../../../node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/dist/cli.mjs" "$@"
17
+ fi
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "@aprovan/patchwork-image-shadcn",
3
+ "version": "0.1.0",
4
+ "description": "Patchwork image: ShadCN/ui with Tailwind CSS and Radix UI",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "package.json"
11
+ ],
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js"
19
+ },
20
+ "./package.json": "./package.json"
21
+ },
22
+ "scripts": {
23
+ "build": "tsup",
24
+ "dev": "tsup --watch",
25
+ "typecheck": "tsc --noEmit"
26
+ },
27
+ "patchwork": {
28
+ "platform": "browser",
29
+ "dependencies": {
30
+ "react": "^18.0.0",
31
+ "react-dom": "^18.0.0"
32
+ },
33
+ "esbuild": {
34
+ "target": "es2020",
35
+ "format": "esm",
36
+ "jsx": "transform",
37
+ "jsxFactory": "React.createElement",
38
+ "jsxFragment": "React.Fragment"
39
+ },
40
+ "framework": {
41
+ "globals": {
42
+ "react": "React",
43
+ "react-dom": "ReactDOM"
44
+ },
45
+ "preload": [
46
+ "https://esm.sh/react@18",
47
+ "https://esm.sh/react-dom@18/client"
48
+ ],
49
+ "deps": {
50
+ "react": "18",
51
+ "react-dom": "18"
52
+ }
53
+ },
54
+ "aliases": {
55
+ "@/components/ui/*": "@packagedcn/react",
56
+ "@/components/*": "@packagedcn/react",
57
+ "@/lib/utils": "@packagedcn/react"
58
+ }
59
+ },
60
+ "dependencies": {
61
+ "react": "^18.0.0",
62
+ "react-dom": "^18.0.0",
63
+ "@radix-ui/react-dialog": "^1.0.0",
64
+ "@radix-ui/react-dropdown-menu": "^2.0.0",
65
+ "@radix-ui/react-slot": "^1.0.0",
66
+ "@radix-ui/react-tooltip": "^1.0.0",
67
+ "class-variance-authority": "^0.7.0",
68
+ "clsx": "^2.0.0",
69
+ "tailwind-merge": "^2.0.0",
70
+ "lucide-react": "^0.400.0"
71
+ },
72
+ "devDependencies": {
73
+ "@types/node": "^22.10.5",
74
+ "@types/react": "^18.0.0",
75
+ "@types/react-dom": "^18.0.0",
76
+ "tsup": "^8.3.5",
77
+ "typescript": "^5.7.3"
78
+ },
79
+ "engines": {
80
+ "node": ">=20.0.0"
81
+ }
82
+ }
@@ -0,0 +1,341 @@
1
+ /**
2
+ * @aprovan/patchwork-image-shadcnshadcn - HTML Generation
3
+ *
4
+ * Generates complete HTML documents for browser widget rendering.
5
+ * The image owns the full HTML template including CSS, import maps, and mounting code.
6
+ *
7
+ * Uses Tailwind Play CDN for runtime CSS generation.
8
+ */
9
+
10
+ import { DEFAULT_CSS_VARIABLES, DARK_CSS_VARIABLES } from './setup.js';
11
+
12
+ export interface HtmlOptions {
13
+ /** Document title */
14
+ title?: string;
15
+ /** Theme: 'light' | 'dark' (default: 'dark') */
16
+ theme?: 'light' | 'dark';
17
+ /** Custom CSS to inject */
18
+ customCss?: string;
19
+ /** Widget props to pass */
20
+ props?: Record<string, unknown>;
21
+ /** Service namespaces to expose (generates bridge code) */
22
+ services?: string[];
23
+ }
24
+
25
+ export interface ImportMapEntry {
26
+ [pkg: string]: string;
27
+ }
28
+
29
+ /**
30
+ * Generate CSS for the selected theme
31
+ */
32
+ function generateThemeCss(theme: 'light' | 'dark'): string {
33
+ const vars = theme === 'dark' ? DARK_CSS_VARIABLES : DEFAULT_CSS_VARIABLES;
34
+ const cssVarsString = Object.entries(vars)
35
+ .map(([key, value]) => ` ${key}: ${value};`)
36
+ .join('\n');
37
+
38
+ return `
39
+ :root {
40
+ ${cssVarsString}
41
+ }
42
+
43
+ * {
44
+ margin: 0;
45
+ padding: 0;
46
+ box-sizing: border-box;
47
+ }
48
+
49
+ body {
50
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
51
+ line-height: 1.5;
52
+ color: hsl(var(--foreground));
53
+ background-color: hsl(var(--background));
54
+ }
55
+
56
+ *, *::before, *::after {
57
+ border-color: hsl(var(--border));
58
+ }
59
+ `;
60
+ }
61
+
62
+ /**
63
+ * Return the Tailwind Play CDN script URL.
64
+ * Play CDN auto-initializes with MutationObserver, generating CSS on-demand.
65
+ */
66
+ function getTailwindCdnScript(): string {
67
+ return 'https://cdn.tailwindcss.com';
68
+ }
69
+
70
+ /**
71
+ * Generate the mounting code for React widgets
72
+ */
73
+ function generateMountCode(propsJson: string): string {
74
+ return `
75
+ import { createRoot } from "react-dom/client";
76
+ import React from "react";
77
+
78
+ // Widget code will set window.__PATCHWORK_WIDGET__
79
+ const Component = window.__PATCHWORK_WIDGET__;
80
+ const props = ${propsJson};
81
+
82
+ if (Component) {
83
+ const root = createRoot(document.getElementById('root'));
84
+ root.render(React.createElement(Component, props));
85
+ window.parent.postMessage({ type: 'patchwork:ready' }, '*');
86
+ } else {
87
+ const root = createRoot(document.getElementById('root'));
88
+ root.render(
89
+ React.createElement('div', { style: { color: 'red', padding: '20px' } },
90
+ React.createElement('h2', null, 'Error: No component found'),
91
+ React.createElement('p', null, 'Widget must export a default component.')
92
+ )
93
+ );
94
+ window.parent.postMessage({ type: 'patchwork:error', message: 'No component found' }, '*');
95
+ }
96
+
97
+ window.addEventListener('error', (e) => {
98
+ window.parent.postMessage({ type: 'patchwork:error', message: e.message }, '*');
99
+ });
100
+ `;
101
+ }
102
+
103
+ /**
104
+ * Transform compiled widget code to set global export
105
+ */
106
+ export function transformWidgetCode(code: string): string {
107
+ let result = code;
108
+
109
+ // Handle: export { X as default }
110
+ const namedMatch = result.match(/export\s*{\s*(\w+)\s+as\s+default\s*}/);
111
+ if (namedMatch) {
112
+ result = result.replace(
113
+ /export\s*{\s*\w+\s+as\s+default\s*};?/,
114
+ `window.__PATCHWORK_WIDGET__ = ${namedMatch[1]};`,
115
+ );
116
+ }
117
+
118
+ // Handle: export default X or export default function X
119
+ const directMatch = result.match(/export\s+default\s+(?:function\s+)?(\w+)/);
120
+ if (directMatch && !namedMatch) {
121
+ result = result.replace(
122
+ /export\s+default\s+(?:function\s+)?(\w+)/,
123
+ `window.__PATCHWORK_WIDGET__ = $1`,
124
+ );
125
+ }
126
+
127
+ // Remove remaining exports
128
+ return result.replace(/export\s*{[^}]*};?/g, '');
129
+ }
130
+
131
+ /**
132
+ * Generate service bridge code for iframe communication
133
+ *
134
+ * Creates JavaScript that sets up:
135
+ * 1. Message handling for service results from parent
136
+ * 2. Dynamic proxy objects for each service namespace
137
+ */
138
+ function generateServiceBridge(services: string[]): string {
139
+ if (services.length === 0) return '';
140
+
141
+ const namespaceAssignments = services
142
+ .map((ns) => `window.${ns} = createNamespaceProxy('${ns}');`)
143
+ .join('\n ');
144
+
145
+ return `
146
+ (function() {
147
+ var pendingCalls = new Map();
148
+
149
+ window.__patchwork_call__ = function(namespace, method, args) {
150
+ return new Promise(function(resolve, reject) {
151
+ var id = Math.random().toString(36).slice(2);
152
+ pendingCalls.set(id, { resolve: resolve, reject: reject });
153
+ window.parent.postMessage({
154
+ type: 'patchwork:call',
155
+ id: id,
156
+ service: namespace,
157
+ method: method,
158
+ args: args
159
+ }, '*');
160
+ setTimeout(function() {
161
+ if (pendingCalls.has(id)) {
162
+ pendingCalls.delete(id);
163
+ reject(new Error('Service call timeout: ' + namespace + '.' + method));
164
+ }
165
+ }, 30000);
166
+ });
167
+ };
168
+
169
+ window.addEventListener('message', function(e) {
170
+ if (e.data && e.data.type === 'patchwork:response') {
171
+ var pending = pendingCalls.get(e.data.id);
172
+ if (pending) {
173
+ pendingCalls.delete(e.data.id);
174
+ if (e.data.result.success) {
175
+ pending.resolve(e.data.result.data);
176
+ } else {
177
+ pending.reject(new Error(e.data.result.error || 'Service call failed'));
178
+ }
179
+ }
180
+ }
181
+ });
182
+
183
+ function createNamespaceProxy(namespace) {
184
+ function createNestedProxy(path) {
185
+ var fn = function() {
186
+ return window.__patchwork_call__(namespace, path, Array.prototype.slice.call(arguments));
187
+ };
188
+ return new Proxy(fn, {
189
+ get: function(_, nestedName) {
190
+ if (typeof nestedName === 'symbol') return undefined;
191
+ var newPath = path ? path + '.' + nestedName : nestedName;
192
+ return createNestedProxy(newPath);
193
+ }
194
+ });
195
+ }
196
+ return new Proxy({}, {
197
+ get: function(_, fieldName) {
198
+ if (typeof fieldName === 'symbol') return undefined;
199
+ return createNestedProxy(fieldName);
200
+ }
201
+ });
202
+ }
203
+
204
+ ${namespaceAssignments}
205
+ })();
206
+ `;
207
+ }
208
+
209
+ /**
210
+ * Generate a complete HTML document for rendering a widget
211
+ *
212
+ * Uses Tailwind Play CDN which detects class usage via MutationObserver and
213
+ * generates CSS on-demand.
214
+ *
215
+ * @param compiledJs - The compiled widget JavaScript code
216
+ * @param importMap - Import map for dependencies
217
+ * @param options - HTML generation options
218
+ */
219
+ export function generateHtml(
220
+ compiledJs: string,
221
+ importMap: ImportMapEntry,
222
+ options: HtmlOptions = {},
223
+ ): string {
224
+ const {
225
+ title = 'Patchwork Widget',
226
+ theme = 'dark',
227
+ customCss = '',
228
+ props = {},
229
+ services = [],
230
+ } = options;
231
+
232
+ const themeCss = generateThemeCss(theme);
233
+ const tailwindCdn = getTailwindCdnScript();
234
+ const widgetCode = transformWidgetCode(compiledJs);
235
+ const importMapJson = JSON.stringify({ imports: importMap }, null, 2);
236
+ const propsJson = JSON.stringify(props);
237
+ const mountCode = generateMountCode(propsJson);
238
+ const serviceBridge = generateServiceBridge(services);
239
+
240
+ return `<!DOCTYPE html>
241
+ <html lang="en" class="${theme}">
242
+ <head>
243
+ <meta charset="UTF-8">
244
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
245
+ <title>${title}</title>
246
+ <!-- Tailwind Play CDN - config must be set BEFORE script loads -->
247
+ <script>
248
+ window.tailwind = {
249
+ config: ${JSON.stringify({
250
+ darkMode: 'class',
251
+ theme: {
252
+ extend: {
253
+ colors: {
254
+ border: 'hsl(var(--border))',
255
+ input: 'hsl(var(--input))',
256
+ ring: 'hsl(var(--ring))',
257
+ background: 'hsl(var(--background))',
258
+ foreground: 'hsl(var(--foreground))',
259
+ primary: {
260
+ DEFAULT: 'hsl(var(--primary))',
261
+ foreground: 'hsl(var(--primary-foreground))',
262
+ },
263
+ secondary: {
264
+ DEFAULT: 'hsl(var(--secondary))',
265
+ foreground: 'hsl(var(--secondary-foreground))',
266
+ },
267
+ destructive: {
268
+ DEFAULT: 'hsl(var(--destructive))',
269
+ foreground: 'hsl(var(--destructive-foreground))',
270
+ },
271
+ muted: {
272
+ DEFAULT: 'hsl(var(--muted))',
273
+ foreground: 'hsl(var(--muted-foreground))',
274
+ },
275
+ accent: {
276
+ DEFAULT: 'hsl(var(--accent))',
277
+ foreground: 'hsl(var(--accent-foreground))',
278
+ },
279
+ popover: {
280
+ DEFAULT: 'hsl(var(--popover))',
281
+ foreground: 'hsl(var(--popover-foreground))',
282
+ },
283
+ card: {
284
+ DEFAULT: 'hsl(var(--card))',
285
+ foreground: 'hsl(var(--card-foreground))',
286
+ },
287
+ },
288
+ borderRadius: {
289
+ lg: 'var(--radius)',
290
+ md: 'calc(var(--radius) - 2px)',
291
+ sm: 'calc(var(--radius) - 4px)',
292
+ },
293
+ },
294
+ },
295
+ })}
296
+ };
297
+ </script>
298
+ <script src="${tailwindCdn}" crossorigin></script>
299
+ <script type="importmap">${importMapJson}</script>
300
+ <style>${themeCss}${customCss}</style>
301
+ </head>
302
+ <body>
303
+ <div id="root"></div>
304
+ <script>
305
+ // Service bridge
306
+ ${serviceBridge}
307
+ </script>
308
+ <script type="module">
309
+ // Widget code
310
+ ${widgetCode}
311
+ </script>
312
+ <script type="module">
313
+ // Mount the widget
314
+ ${mountCode}
315
+ </script>
316
+ </body>
317
+ </html>`;
318
+ }
319
+
320
+ /**
321
+ * Get the default import map for this image
322
+ */
323
+ export function getDefaultImportMap(cdn = 'https://esm.sh'): ImportMapEntry {
324
+ return {
325
+ react: `${cdn}/react@18`,
326
+ 'react/': `${cdn}/react@18/`,
327
+ 'react-dom': `${cdn}/react-dom@18`,
328
+ 'react-dom/': `${cdn}/react-dom@18/`,
329
+ 'react-dom/client': `${cdn}/react-dom@18/client`,
330
+ };
331
+ }
332
+
333
+ /**
334
+ * Get framework dependencies declared by this image
335
+ */
336
+ export function getFrameworkDependencies(): Record<string, string> {
337
+ return {
338
+ react: '^18.0.0',
339
+ 'react-dom': '^18.0.0',
340
+ };
341
+ }