@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,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,27 @@
1
+ {
2
+ "name": "@aprovan/patchwork",
3
+ "version": "0.1.0",
4
+ "description": "Patchwork, a platform for building LLM-powered applications with pluggable UI components and a flexible compiler.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "scripts": {
15
+ "build": "tsup",
16
+ "check-types": "tsc --noEmit",
17
+ "dev": "tsup --watch",
18
+ "typecheck": "tsc --noEmit"
19
+ },
20
+ "devDependencies": {
21
+ "tsup": "^8.3.5",
22
+ "typescript": "^5.7.3"
23
+ },
24
+ "engines": {
25
+ "node": ">=20.0.0"
26
+ }
27
+ }
@@ -0,0 +1,15 @@
1
+ export * from './types';
2
+
3
+ export type { CacheConfig, ServiceResult } from './services/types.js';
4
+
5
+ // Services
6
+ export {
7
+ createServiceProxy,
8
+ callProcedure,
9
+ batchCall,
10
+ configureCacheTtl,
11
+ invalidateCache,
12
+ getCacheStats,
13
+ setServiceBackend,
14
+ type ServiceBackend,
15
+ } from './services/index.js';
@@ -0,0 +1,11 @@
1
+ export {
2
+ createServiceProxy,
3
+ callProcedure,
4
+ batchCall,
5
+ configureCacheTtl,
6
+ invalidateCache,
7
+ getCacheStats,
8
+ setServiceBackend,
9
+ type ServiceBackend,
10
+ type BatchCall,
11
+ } from './proxy';
@@ -0,0 +1,213 @@
1
+ // Service Proxy - Caching layer for service calls
2
+ //
3
+ // Provides a backend-agnostic service proxy with caching.
4
+ // The actual backend (UTCP, MCP, HTTP, etc.) is set via setServiceBackend().
5
+
6
+ import type { ServiceResult, CacheEntry, CacheConfig } from './types';
7
+
8
+ /**
9
+ * Service backend interface - abstracts the actual service call mechanism
10
+ *
11
+ * Implementations can use UTCP, MCP, HTTP, or any other protocol.
12
+ */
13
+ export interface ServiceBackend {
14
+ /**
15
+ * Call a service procedure
16
+ * @param service - Service namespace (e.g., "git", "github")
17
+ * @param procedure - Procedure name (e.g., "branch", "repos.list")
18
+ * @param args - Arguments to pass
19
+ */
20
+ call(service: string, procedure: string, args: unknown[]): Promise<unknown>;
21
+ }
22
+
23
+ // Current backend (must be set before use)
24
+ let currentBackend: ServiceBackend | null = null;
25
+
26
+ // Cache storage
27
+ const cache = new Map<string, CacheEntry>();
28
+ const cacheConfig = new Map<string, CacheConfig>();
29
+ const MAX_CACHE_SIZE = 1000;
30
+
31
+ /**
32
+ * Set the service backend
33
+ *
34
+ * This must be called before making any service calls.
35
+ * The backend handles the actual communication with services.
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * // Using with UTCP
40
+ * setServiceBackend({
41
+ * call: (service, procedure, args) =>
42
+ * utcpClient.callTool(`${service}.${procedure}`, args)
43
+ * });
44
+ *
45
+ * // Using with HTTP proxy
46
+ * setServiceBackend({
47
+ * call: async (service, procedure, args) => {
48
+ * const res = await fetch(`/api/proxy/${service}/${procedure}`, {
49
+ * method: 'POST',
50
+ * body: JSON.stringify({ args })
51
+ * });
52
+ * return res.json();
53
+ * }
54
+ * });
55
+ * ```
56
+ */
57
+ export function setServiceBackend(backend: ServiceBackend): void {
58
+ currentBackend = backend;
59
+ }
60
+
61
+ /**
62
+ * Create a service proxy that wraps the backend with caching
63
+ */
64
+ export function createServiceProxy(): ServiceBackend {
65
+ return {
66
+ call: (service, procedure, args) =>
67
+ callProcedure(service, procedure, args).then((r) => {
68
+ if (!r.success) throw new Error(r.error || 'Service call failed');
69
+ return r.data;
70
+ }),
71
+ };
72
+ }
73
+
74
+ function getCacheKey(
75
+ service: string,
76
+ procedure: string,
77
+ args: unknown[],
78
+ ): string {
79
+ return `${service}:${procedure}:${JSON.stringify(args)}`;
80
+ }
81
+
82
+ function evictOldestCache(): void {
83
+ if (cache.size < MAX_CACHE_SIZE) return;
84
+ const oldest = Array.from(cache.entries())
85
+ .sort(([, a], [, b]) => a.expiresAt - b.expiresAt)
86
+ .slice(0, Math.floor(MAX_CACHE_SIZE * 0.2));
87
+ for (const [key] of oldest) cache.delete(key);
88
+ }
89
+
90
+ function getFromCache(key: string): ServiceResult | null {
91
+ const entry = cache.get(key);
92
+ if (!entry) return null;
93
+ if (Date.now() > entry.expiresAt) {
94
+ cache.delete(key);
95
+ return null;
96
+ }
97
+ return { ...entry.result, cached: true };
98
+ }
99
+
100
+ function setCache(key: string, result: ServiceResult, ttl: number): void {
101
+ evictOldestCache();
102
+ cache.set(key, { result, expiresAt: Date.now() + ttl * 1000 });
103
+ }
104
+
105
+ /**
106
+ * Call a service procedure
107
+ *
108
+ * @param service - Service namespace (e.g., "git", "github")
109
+ * @param procedure - Procedure name (e.g., "branch", "repos.get")
110
+ * @param args - Arguments to pass
111
+ * @param options - Call options
112
+ */
113
+ export async function callProcedure(
114
+ service: string,
115
+ procedure: string,
116
+ args: unknown[] = [],
117
+ options: { bypassCache?: boolean } = {},
118
+ ): Promise<ServiceResult> {
119
+ const cacheKey = getCacheKey(service, procedure, args);
120
+ const ttlConfig = cacheConfig.get(service);
121
+
122
+ // Check cache first
123
+ if (!options.bypassCache && ttlConfig) {
124
+ const cached = getFromCache(cacheKey);
125
+ if (cached) return cached;
126
+ }
127
+
128
+ // Check if backend is configured
129
+ if (!currentBackend) {
130
+ return {
131
+ success: false,
132
+ error: 'No service backend configured. Call setServiceBackend() first.',
133
+ durationMs: 0,
134
+ };
135
+ }
136
+
137
+ const startTime = performance.now();
138
+
139
+ try {
140
+ const data = await currentBackend.call(service, procedure, args);
141
+
142
+ const serviceResult: ServiceResult = {
143
+ success: true,
144
+ data,
145
+ durationMs: performance.now() - startTime,
146
+ };
147
+
148
+ // Cache successful results
149
+ if (ttlConfig) {
150
+ setCache(cacheKey, serviceResult, ttlConfig.ttl);
151
+ }
152
+
153
+ return serviceResult;
154
+ } catch (err) {
155
+ return {
156
+ success: false,
157
+ error: err instanceof Error ? err.message : String(err),
158
+ durationMs: performance.now() - startTime,
159
+ };
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Configure cache TTL for a service
165
+ */
166
+ export function configureCacheTtl(service: string, ttl: number): void {
167
+ cacheConfig.set(service, { ttl });
168
+ }
169
+
170
+ /**
171
+ * Invalidate cache entries
172
+ */
173
+ export function invalidateCache(service?: string): void {
174
+ if (service) {
175
+ for (const key of cache.keys()) {
176
+ if (key.startsWith(`${service}:`)) cache.delete(key);
177
+ }
178
+ } else {
179
+ cache.clear();
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Get cache statistics
185
+ */
186
+ export function getCacheStats(): { size: number; services: string[] } {
187
+ const services = new Set<string>();
188
+ for (const key of cache.keys()) {
189
+ const service = key.split(':')[0];
190
+ if (service) services.add(service);
191
+ }
192
+ return { size: cache.size, services: [...services] };
193
+ }
194
+
195
+ /**
196
+ * Batch call multiple procedures
197
+ */
198
+ export interface BatchCall {
199
+ service: string;
200
+ procedure: string;
201
+ args?: unknown[];
202
+ bypassCache?: boolean;
203
+ }
204
+
205
+ export async function batchCall(calls: BatchCall[]): Promise<ServiceResult[]> {
206
+ return Promise.all(
207
+ calls.map((c) =>
208
+ callProcedure(c.service, c.procedure, c.args || [], {
209
+ bypassCache: c.bypassCache,
210
+ }),
211
+ ),
212
+ );
213
+ }
@@ -0,0 +1,28 @@
1
+ // Service Types - Core types for the service proxy system
2
+
3
+ /**
4
+ * Result of a service call
5
+ */
6
+ export interface ServiceResult<T = unknown> {
7
+ success: boolean;
8
+ data?: T;
9
+ error?: string;
10
+ cached?: boolean;
11
+ durationMs: number;
12
+ }
13
+
14
+ /**
15
+ * Cache configuration for a service
16
+ */
17
+ export interface CacheConfig {
18
+ /** TTL in seconds */
19
+ ttl: number;
20
+ }
21
+
22
+ /**
23
+ * Cache entry
24
+ */
25
+ export interface CacheEntry {
26
+ result: ServiceResult;
27
+ expiresAt: number;
28
+ }
@@ -0,0 +1,116 @@
1
+ // Patchwork Types - Context providers and selection engine types
2
+
3
+ // ============================================================================
4
+ // Context Provider Types
5
+ // ============================================================================
6
+
7
+ export interface ContextProvider {
8
+ name: string;
9
+ schema?: Record<string, unknown>;
10
+ getContext(): Promise<Record<string, unknown>>;
11
+ subscribe?(callback: (context: Record<string, unknown>) => void): () => void;
12
+ }
13
+
14
+ export interface AggregatedContext {
15
+ timestamp: string;
16
+ providers: {
17
+ [providerName: string]: Record<string, unknown>;
18
+ };
19
+ }
20
+
21
+ export interface ContextManagerOptions {
22
+ debounce_ms?: number;
23
+ }
24
+
25
+ // ============================================================================
26
+ // Common Context Shapes
27
+ // ============================================================================
28
+
29
+ export interface ShellContext {
30
+ cwd: string;
31
+ recent_commands?: string[];
32
+ shell?: string;
33
+ }
34
+
35
+ export interface GitContext {
36
+ is_repo: boolean;
37
+ branch?: string;
38
+ remote_url?: string;
39
+ uncommitted_changes?: number;
40
+ staged_files?: number;
41
+ }
42
+
43
+ export interface ProjectContext {
44
+ type?: string;
45
+ package_manager?: string;
46
+ scripts?: string[];
47
+ }
48
+
49
+ // ============================================================================
50
+ // Selection Engine Types
51
+ // ============================================================================
52
+
53
+ export interface Viewport {
54
+ width: number;
55
+ height: number;
56
+ }
57
+
58
+ export interface SelectionOptions {
59
+ limit?: number;
60
+ strategy?: 'llm' | 'rules';
61
+ minConfidence?: number;
62
+ }
63
+
64
+ export interface WidgetSuggestion {
65
+ name: string;
66
+ confidence: number;
67
+ position: 'primary' | 'secondary' | 'ambient';
68
+ reason: string;
69
+ suggested_size: {
70
+ width: number;
71
+ height: number;
72
+ };
73
+ }
74
+
75
+ export interface CompositionRules {
76
+ max_primary: number;
77
+ max_secondary: number;
78
+ max_ambient: number;
79
+ ambient_stacking: boolean;
80
+ }
81
+
82
+ export const DEFAULT_COMPOSITION_RULES: CompositionRules = {
83
+ max_primary: 1,
84
+ max_secondary: 3,
85
+ max_ambient: 5,
86
+ ambient_stacking: true,
87
+ };
88
+
89
+ export interface ComposedLayout {
90
+ widgets: Array<{
91
+ name: string;
92
+ position: 'primary' | 'secondary' | 'ambient';
93
+ bounds: { x: number; y: number; width: number; height: number };
94
+ }>;
95
+ remaining_space: { width: number; height: number };
96
+ }
97
+
98
+ // ============================================================================
99
+ // Usage Tracking Types
100
+ // ============================================================================
101
+
102
+ export interface UsageRecord {
103
+ widget_name: string;
104
+ context_hash: string;
105
+ was_suggested: boolean;
106
+ viewport: Viewport;
107
+ timestamp: string;
108
+ }
109
+
110
+ export interface UsagePattern {
111
+ context_hash: string;
112
+ selected_widget: string;
113
+ was_suggested: boolean;
114
+ viewport_size: Viewport;
115
+ timestamp: string;
116
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src"
6
+ },
7
+ "include": ["src/**/*"]
8
+ }
@@ -0,0 +1,14 @@
1
+ import { defineConfig } from 'tsup';
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.ts'],
5
+ format: ['esm'],
6
+ target: 'node20',
7
+ clean: true,
8
+ dts: true,
9
+ splitting: false,
10
+ sourcemap: true,
11
+ shims: true,
12
+ external: ['react', 'react-dom'],
13
+ skipNodeModulesBundle: true,
14
+ });
@@ -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,40 @@
1
+ {
2
+ "name": "@aprovan/stitchery",
3
+ "version": "0.1.0",
4
+ "description": "Backend services for LLM-generated artifacts",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "stitchery": "./dist/cli.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ },
16
+ "./server": {
17
+ "types": "./dist/server/index.d.ts",
18
+ "import": "./dist/server/index.js"
19
+ }
20
+ },
21
+ "scripts": {
22
+ "build": "tsup",
23
+ "dev": "tsup --watch",
24
+ "typecheck": "tsc --noEmit",
25
+ "start": "node dist/cli.js"
26
+ },
27
+ "dependencies": {
28
+ "@ai-sdk/mcp": "^1.0.18",
29
+ "@ai-sdk/openai-compatible": "^2.0.26",
30
+ "@aprovan/patchwork-utcp": "workspace:^",
31
+ "ai": "^6.0.67",
32
+ "commander": "^12.1.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^22.14.1",
36
+ "tsup": "^8.4.0",
37
+ "typescript": "^5.8.2"
38
+ },
39
+ "license": "MIT"
40
+ }