whale-code 6.4.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 (319) hide show
  1. package/README.md +95 -0
  2. package/bin/swag-agent.js +9 -0
  3. package/bin/swagmanager-mcp.js +321 -0
  4. package/dist/cli/app.d.ts +26 -0
  5. package/dist/cli/app.js +64 -0
  6. package/dist/cli/chat/AgentSelector.d.ts +14 -0
  7. package/dist/cli/chat/AgentSelector.js +14 -0
  8. package/dist/cli/chat/ChatApp.d.ts +9 -0
  9. package/dist/cli/chat/ChatApp.js +267 -0
  10. package/dist/cli/chat/ChatInput.d.ts +39 -0
  11. package/dist/cli/chat/ChatInput.js +509 -0
  12. package/dist/cli/chat/MarkdownText.d.ts +10 -0
  13. package/dist/cli/chat/MarkdownText.js +20 -0
  14. package/dist/cli/chat/MessageList.d.ts +37 -0
  15. package/dist/cli/chat/MessageList.js +80 -0
  16. package/dist/cli/chat/ModelSelector.d.ts +20 -0
  17. package/dist/cli/chat/ModelSelector.js +73 -0
  18. package/dist/cli/chat/RewindViewer.d.ts +26 -0
  19. package/dist/cli/chat/RewindViewer.js +185 -0
  20. package/dist/cli/chat/StoreSelector.d.ts +14 -0
  21. package/dist/cli/chat/StoreSelector.js +24 -0
  22. package/dist/cli/chat/StreamingText.d.ts +12 -0
  23. package/dist/cli/chat/StreamingText.js +12 -0
  24. package/dist/cli/chat/SubagentPanel.d.ts +45 -0
  25. package/dist/cli/chat/SubagentPanel.js +110 -0
  26. package/dist/cli/chat/TeamPanel.d.ts +21 -0
  27. package/dist/cli/chat/TeamPanel.js +42 -0
  28. package/dist/cli/chat/ToolIndicator.d.ts +25 -0
  29. package/dist/cli/chat/ToolIndicator.js +436 -0
  30. package/dist/cli/chat/hooks/useAgentLoop.d.ts +39 -0
  31. package/dist/cli/chat/hooks/useAgentLoop.js +382 -0
  32. package/dist/cli/chat/hooks/useSlashCommands.d.ts +37 -0
  33. package/dist/cli/chat/hooks/useSlashCommands.js +387 -0
  34. package/dist/cli/commands/config-cmd.d.ts +10 -0
  35. package/dist/cli/commands/config-cmd.js +99 -0
  36. package/dist/cli/commands/doctor.d.ts +14 -0
  37. package/dist/cli/commands/doctor.js +172 -0
  38. package/dist/cli/commands/init.d.ts +16 -0
  39. package/dist/cli/commands/init.js +278 -0
  40. package/dist/cli/commands/mcp.d.ts +12 -0
  41. package/dist/cli/commands/mcp.js +162 -0
  42. package/dist/cli/login/LoginApp.d.ts +7 -0
  43. package/dist/cli/login/LoginApp.js +157 -0
  44. package/dist/cli/print-mode.d.ts +31 -0
  45. package/dist/cli/print-mode.js +202 -0
  46. package/dist/cli/serve-mode.d.ts +37 -0
  47. package/dist/cli/serve-mode.js +636 -0
  48. package/dist/cli/services/agent-definitions.d.ts +25 -0
  49. package/dist/cli/services/agent-definitions.js +91 -0
  50. package/dist/cli/services/agent-events.d.ts +178 -0
  51. package/dist/cli/services/agent-events.js +175 -0
  52. package/dist/cli/services/agent-loop.d.ts +90 -0
  53. package/dist/cli/services/agent-loop.js +762 -0
  54. package/dist/cli/services/agent-worker-base.d.ts +97 -0
  55. package/dist/cli/services/agent-worker-base.js +220 -0
  56. package/dist/cli/services/auth-service.d.ts +30 -0
  57. package/dist/cli/services/auth-service.js +160 -0
  58. package/dist/cli/services/background-processes.d.ts +126 -0
  59. package/dist/cli/services/background-processes.js +318 -0
  60. package/dist/cli/services/browser-auth.d.ts +24 -0
  61. package/dist/cli/services/browser-auth.js +180 -0
  62. package/dist/cli/services/claude-md-loader.d.ts +16 -0
  63. package/dist/cli/services/claude-md-loader.js +58 -0
  64. package/dist/cli/services/config-store.d.ts +47 -0
  65. package/dist/cli/services/config-store.js +79 -0
  66. package/dist/cli/services/debug-log.d.ts +10 -0
  67. package/dist/cli/services/debug-log.js +52 -0
  68. package/dist/cli/services/error-logger.d.ts +58 -0
  69. package/dist/cli/services/error-logger.js +269 -0
  70. package/dist/cli/services/file-history.d.ts +21 -0
  71. package/dist/cli/services/file-history.js +83 -0
  72. package/dist/cli/services/format-server-response.d.ts +16 -0
  73. package/dist/cli/services/format-server-response.js +440 -0
  74. package/dist/cli/services/git-context.d.ts +11 -0
  75. package/dist/cli/services/git-context.js +66 -0
  76. package/dist/cli/services/hooks.d.ts +85 -0
  77. package/dist/cli/services/hooks.js +258 -0
  78. package/dist/cli/services/interactive-tools.d.ts +125 -0
  79. package/dist/cli/services/interactive-tools.js +260 -0
  80. package/dist/cli/services/keybinding-manager.d.ts +52 -0
  81. package/dist/cli/services/keybinding-manager.js +115 -0
  82. package/dist/cli/services/local-tools.d.ts +22 -0
  83. package/dist/cli/services/local-tools.js +697 -0
  84. package/dist/cli/services/lsp-manager.d.ts +18 -0
  85. package/dist/cli/services/lsp-manager.js +717 -0
  86. package/dist/cli/services/mcp-client.d.ts +48 -0
  87. package/dist/cli/services/mcp-client.js +157 -0
  88. package/dist/cli/services/memory-manager.d.ts +16 -0
  89. package/dist/cli/services/memory-manager.js +57 -0
  90. package/dist/cli/services/model-manager.d.ts +18 -0
  91. package/dist/cli/services/model-manager.js +71 -0
  92. package/dist/cli/services/model-router.d.ts +26 -0
  93. package/dist/cli/services/model-router.js +149 -0
  94. package/dist/cli/services/permission-modes.d.ts +13 -0
  95. package/dist/cli/services/permission-modes.js +43 -0
  96. package/dist/cli/services/rewind.d.ts +84 -0
  97. package/dist/cli/services/rewind.js +194 -0
  98. package/dist/cli/services/ripgrep.d.ts +28 -0
  99. package/dist/cli/services/ripgrep.js +138 -0
  100. package/dist/cli/services/sandbox.d.ts +29 -0
  101. package/dist/cli/services/sandbox.js +97 -0
  102. package/dist/cli/services/server-tools.d.ts +61 -0
  103. package/dist/cli/services/server-tools.js +543 -0
  104. package/dist/cli/services/session-persistence.d.ts +23 -0
  105. package/dist/cli/services/session-persistence.js +99 -0
  106. package/dist/cli/services/subagent-worker.d.ts +19 -0
  107. package/dist/cli/services/subagent-worker.js +41 -0
  108. package/dist/cli/services/subagent.d.ts +47 -0
  109. package/dist/cli/services/subagent.js +647 -0
  110. package/dist/cli/services/system-prompt.d.ts +7 -0
  111. package/dist/cli/services/system-prompt.js +198 -0
  112. package/dist/cli/services/team-lead.d.ts +73 -0
  113. package/dist/cli/services/team-lead.js +512 -0
  114. package/dist/cli/services/team-state.d.ts +77 -0
  115. package/dist/cli/services/team-state.js +398 -0
  116. package/dist/cli/services/teammate.d.ts +31 -0
  117. package/dist/cli/services/teammate.js +689 -0
  118. package/dist/cli/services/telemetry.d.ts +61 -0
  119. package/dist/cli/services/telemetry.js +209 -0
  120. package/dist/cli/services/tools/agent-tools.d.ts +14 -0
  121. package/dist/cli/services/tools/agent-tools.js +347 -0
  122. package/dist/cli/services/tools/file-ops.d.ts +15 -0
  123. package/dist/cli/services/tools/file-ops.js +487 -0
  124. package/dist/cli/services/tools/search-tools.d.ts +8 -0
  125. package/dist/cli/services/tools/search-tools.js +186 -0
  126. package/dist/cli/services/tools/shell-exec.d.ts +10 -0
  127. package/dist/cli/services/tools/shell-exec.js +168 -0
  128. package/dist/cli/services/tools/task-manager.d.ts +28 -0
  129. package/dist/cli/services/tools/task-manager.js +209 -0
  130. package/dist/cli/services/tools/web-tools.d.ts +11 -0
  131. package/dist/cli/services/tools/web-tools.js +395 -0
  132. package/dist/cli/setup/SetupApp.d.ts +9 -0
  133. package/dist/cli/setup/SetupApp.js +191 -0
  134. package/dist/cli/shared/MatrixIntro.d.ts +4 -0
  135. package/dist/cli/shared/MatrixIntro.js +83 -0
  136. package/dist/cli/shared/Theme.d.ts +74 -0
  137. package/dist/cli/shared/Theme.js +127 -0
  138. package/dist/cli/shared/WhaleBanner.d.ts +10 -0
  139. package/dist/cli/shared/WhaleBanner.js +12 -0
  140. package/dist/cli/shared/markdown.d.ts +21 -0
  141. package/dist/cli/shared/markdown.js +756 -0
  142. package/dist/cli/status/StatusApp.d.ts +4 -0
  143. package/dist/cli/status/StatusApp.js +105 -0
  144. package/dist/cli/stores/StoreApp.d.ts +7 -0
  145. package/dist/cli/stores/StoreApp.js +81 -0
  146. package/dist/index.d.ts +15 -0
  147. package/dist/index.js +538 -0
  148. package/dist/local-agent/connection.d.ts +48 -0
  149. package/dist/local-agent/connection.js +332 -0
  150. package/dist/local-agent/discovery.d.ts +18 -0
  151. package/dist/local-agent/discovery.js +146 -0
  152. package/dist/local-agent/executor.d.ts +34 -0
  153. package/dist/local-agent/executor.js +241 -0
  154. package/dist/local-agent/index.d.ts +14 -0
  155. package/dist/local-agent/index.js +198 -0
  156. package/dist/node/adapters/base.d.ts +35 -0
  157. package/dist/node/adapters/base.js +10 -0
  158. package/dist/node/adapters/discord.d.ts +29 -0
  159. package/dist/node/adapters/discord.js +299 -0
  160. package/dist/node/adapters/email.d.ts +23 -0
  161. package/dist/node/adapters/email.js +218 -0
  162. package/dist/node/adapters/imessage.d.ts +17 -0
  163. package/dist/node/adapters/imessage.js +118 -0
  164. package/dist/node/adapters/slack.d.ts +26 -0
  165. package/dist/node/adapters/slack.js +259 -0
  166. package/dist/node/adapters/sms.d.ts +23 -0
  167. package/dist/node/adapters/sms.js +161 -0
  168. package/dist/node/adapters/telegram.d.ts +17 -0
  169. package/dist/node/adapters/telegram.js +101 -0
  170. package/dist/node/adapters/webchat.d.ts +27 -0
  171. package/dist/node/adapters/webchat.js +160 -0
  172. package/dist/node/adapters/whatsapp.d.ts +28 -0
  173. package/dist/node/adapters/whatsapp.js +230 -0
  174. package/dist/node/cli.d.ts +2 -0
  175. package/dist/node/cli.js +325 -0
  176. package/dist/node/config.d.ts +17 -0
  177. package/dist/node/config.js +31 -0
  178. package/dist/node/runtime.d.ts +50 -0
  179. package/dist/node/runtime.js +351 -0
  180. package/dist/server/handlers/__test-utils__/mock-supabase.d.ts +11 -0
  181. package/dist/server/handlers/__test-utils__/mock-supabase.js +393 -0
  182. package/dist/server/handlers/analytics.d.ts +17 -0
  183. package/dist/server/handlers/analytics.js +266 -0
  184. package/dist/server/handlers/api-keys.d.ts +6 -0
  185. package/dist/server/handlers/api-keys.js +221 -0
  186. package/dist/server/handlers/billing.d.ts +33 -0
  187. package/dist/server/handlers/billing.js +272 -0
  188. package/dist/server/handlers/browser.d.ts +10 -0
  189. package/dist/server/handlers/browser.js +517 -0
  190. package/dist/server/handlers/catalog.d.ts +99 -0
  191. package/dist/server/handlers/catalog.js +976 -0
  192. package/dist/server/handlers/comms.d.ts +254 -0
  193. package/dist/server/handlers/comms.js +588 -0
  194. package/dist/server/handlers/creations.d.ts +6 -0
  195. package/dist/server/handlers/creations.js +479 -0
  196. package/dist/server/handlers/crm.d.ts +89 -0
  197. package/dist/server/handlers/crm.js +538 -0
  198. package/dist/server/handlers/discovery.d.ts +6 -0
  199. package/dist/server/handlers/discovery.js +288 -0
  200. package/dist/server/handlers/embeddings.d.ts +92 -0
  201. package/dist/server/handlers/embeddings.js +197 -0
  202. package/dist/server/handlers/enrichment.d.ts +8 -0
  203. package/dist/server/handlers/enrichment.js +768 -0
  204. package/dist/server/handlers/image-gen.d.ts +6 -0
  205. package/dist/server/handlers/image-gen.js +409 -0
  206. package/dist/server/handlers/inventory.d.ts +319 -0
  207. package/dist/server/handlers/inventory.js +447 -0
  208. package/dist/server/handlers/kali.d.ts +10 -0
  209. package/dist/server/handlers/kali.js +210 -0
  210. package/dist/server/handlers/llm-providers.d.ts +6 -0
  211. package/dist/server/handlers/llm-providers.js +673 -0
  212. package/dist/server/handlers/local-agent.d.ts +6 -0
  213. package/dist/server/handlers/local-agent.js +118 -0
  214. package/dist/server/handlers/meta-ads.d.ts +111 -0
  215. package/dist/server/handlers/meta-ads.js +2279 -0
  216. package/dist/server/handlers/nodes.d.ts +33 -0
  217. package/dist/server/handlers/nodes.js +699 -0
  218. package/dist/server/handlers/operations.d.ts +138 -0
  219. package/dist/server/handlers/operations.js +131 -0
  220. package/dist/server/handlers/platform.d.ts +23 -0
  221. package/dist/server/handlers/platform.js +227 -0
  222. package/dist/server/handlers/supply-chain.d.ts +19 -0
  223. package/dist/server/handlers/supply-chain.js +327 -0
  224. package/dist/server/handlers/transcription.d.ts +17 -0
  225. package/dist/server/handlers/transcription.js +121 -0
  226. package/dist/server/handlers/video-gen.d.ts +6 -0
  227. package/dist/server/handlers/video-gen.js +466 -0
  228. package/dist/server/handlers/voice.d.ts +8 -0
  229. package/dist/server/handlers/voice.js +1146 -0
  230. package/dist/server/handlers/workflow-steps.d.ts +86 -0
  231. package/dist/server/handlers/workflow-steps.js +2349 -0
  232. package/dist/server/handlers/workflows.d.ts +7 -0
  233. package/dist/server/handlers/workflows.js +989 -0
  234. package/dist/server/index.d.ts +1 -0
  235. package/dist/server/index.js +2427 -0
  236. package/dist/server/lib/batch-client.d.ts +80 -0
  237. package/dist/server/lib/batch-client.js +467 -0
  238. package/dist/server/lib/code-worker-pool.d.ts +31 -0
  239. package/dist/server/lib/code-worker-pool.js +224 -0
  240. package/dist/server/lib/code-worker.d.ts +1 -0
  241. package/dist/server/lib/code-worker.js +188 -0
  242. package/dist/server/lib/compaction-service.d.ts +32 -0
  243. package/dist/server/lib/compaction-service.js +162 -0
  244. package/dist/server/lib/logger.d.ts +19 -0
  245. package/dist/server/lib/logger.js +46 -0
  246. package/dist/server/lib/otel.d.ts +38 -0
  247. package/dist/server/lib/otel.js +126 -0
  248. package/dist/server/lib/pg-rate-limiter.d.ts +21 -0
  249. package/dist/server/lib/pg-rate-limiter.js +86 -0
  250. package/dist/server/lib/prompt-sanitizer.d.ts +37 -0
  251. package/dist/server/lib/prompt-sanitizer.js +177 -0
  252. package/dist/server/lib/provider-capabilities.d.ts +85 -0
  253. package/dist/server/lib/provider-capabilities.js +190 -0
  254. package/dist/server/lib/provider-failover.d.ts +74 -0
  255. package/dist/server/lib/provider-failover.js +210 -0
  256. package/dist/server/lib/rate-limiter.d.ts +39 -0
  257. package/dist/server/lib/rate-limiter.js +147 -0
  258. package/dist/server/lib/server-agent-loop.d.ts +107 -0
  259. package/dist/server/lib/server-agent-loop.js +667 -0
  260. package/dist/server/lib/server-subagent.d.ts +78 -0
  261. package/dist/server/lib/server-subagent.js +203 -0
  262. package/dist/server/lib/session-checkpoint.d.ts +51 -0
  263. package/dist/server/lib/session-checkpoint.js +145 -0
  264. package/dist/server/lib/ssrf-guard.d.ts +13 -0
  265. package/dist/server/lib/ssrf-guard.js +240 -0
  266. package/dist/server/lib/supabase-client.d.ts +7 -0
  267. package/dist/server/lib/supabase-client.js +78 -0
  268. package/dist/server/lib/template-resolver.d.ts +31 -0
  269. package/dist/server/lib/template-resolver.js +215 -0
  270. package/dist/server/lib/utils.d.ts +16 -0
  271. package/dist/server/lib/utils.js +147 -0
  272. package/dist/server/local-agent-gateway.d.ts +82 -0
  273. package/dist/server/local-agent-gateway.js +426 -0
  274. package/dist/server/providers/anthropic.d.ts +20 -0
  275. package/dist/server/providers/anthropic.js +199 -0
  276. package/dist/server/providers/bedrock.d.ts +20 -0
  277. package/dist/server/providers/bedrock.js +194 -0
  278. package/dist/server/providers/gemini.d.ts +24 -0
  279. package/dist/server/providers/gemini.js +486 -0
  280. package/dist/server/providers/openai.d.ts +24 -0
  281. package/dist/server/providers/openai.js +522 -0
  282. package/dist/server/providers/registry.d.ts +32 -0
  283. package/dist/server/providers/registry.js +58 -0
  284. package/dist/server/providers/shared.d.ts +32 -0
  285. package/dist/server/providers/shared.js +124 -0
  286. package/dist/server/providers/types.d.ts +92 -0
  287. package/dist/server/providers/types.js +12 -0
  288. package/dist/server/proxy-handlers.d.ts +6 -0
  289. package/dist/server/proxy-handlers.js +89 -0
  290. package/dist/server/tool-router.d.ts +149 -0
  291. package/dist/server/tool-router.js +803 -0
  292. package/dist/server/validation.d.ts +24 -0
  293. package/dist/server/validation.js +301 -0
  294. package/dist/server/worker.d.ts +19 -0
  295. package/dist/server/worker.js +201 -0
  296. package/dist/setup.d.ts +8 -0
  297. package/dist/setup.js +181 -0
  298. package/dist/shared/agent-core.d.ts +157 -0
  299. package/dist/shared/agent-core.js +534 -0
  300. package/dist/shared/anthropic-types.d.ts +105 -0
  301. package/dist/shared/anthropic-types.js +7 -0
  302. package/dist/shared/api-client.d.ts +90 -0
  303. package/dist/shared/api-client.js +379 -0
  304. package/dist/shared/constants.d.ts +33 -0
  305. package/dist/shared/constants.js +80 -0
  306. package/dist/shared/sse-parser.d.ts +26 -0
  307. package/dist/shared/sse-parser.js +259 -0
  308. package/dist/shared/tool-dispatch.d.ts +52 -0
  309. package/dist/shared/tool-dispatch.js +191 -0
  310. package/dist/shared/types.d.ts +72 -0
  311. package/dist/shared/types.js +7 -0
  312. package/dist/updater.d.ts +25 -0
  313. package/dist/updater.js +140 -0
  314. package/dist/webchat/widget.d.ts +0 -0
  315. package/dist/webchat/widget.js +397 -0
  316. package/package.json +95 -0
  317. package/src/cli/services/builtin-skills/commit.md +19 -0
  318. package/src/cli/services/builtin-skills/review-pr.md +21 -0
  319. package/src/cli/services/builtin-skills/review.md +18 -0
@@ -0,0 +1,479 @@
1
+ // server/handlers/creations.ts — Creation management (TV menus, landing pages, dashboards)
2
+ // CRUD, AI generation via LLM, screenshot previews via browser, collection management
3
+ import { sanitizeFilterValue } from "../lib/utils.js";
4
+ import { MODELS } from "../../shared/constants.js";
5
+ import { handleLLM } from "./llm-providers.js";
6
+ import { handleBrowser } from "./browser.js";
7
+ // ============================================================================
8
+ // HELPERS
9
+ // ============================================================================
10
+ function slugify(text) {
11
+ return text
12
+ .toLowerCase()
13
+ .replace(/[^a-z0-9]+/g, "-")
14
+ .replace(/^-+|-+$/g, "")
15
+ .substring(0, 80)
16
+ + "-" + Math.random().toString(36).substring(2, 8);
17
+ }
18
+ // ============================================================================
19
+ // CONSTANTS
20
+ // ============================================================================
21
+ const STOREFRONT_URL = process.env.STOREFRONT_URL || "https://floradistro.com";
22
+ const CREATION_LIST_COLS = "id, name, creation_type, status, slug, display_mode, visibility, location_id, thumbnail_url, created_at, updated_at";
23
+ const CREATION_FULL_COLS = "id, name, creation_type, status, slug, display_mode, visibility, location_id, thumbnail_url, description, react_code, data_config, theme_config, layout_config, created_at, updated_at";
24
+ // ============================================================================
25
+ // GENERATION SYSTEM PROMPT
26
+ // ============================================================================
27
+ const GENERATION_SYSTEM_PROMPT = `You are a React component generator for a digital signage / storefront creation platform.
28
+
29
+ ## Output Format
30
+ Return ONLY the React component code. No markdown fences, no explanation, no imports.
31
+ The code will be rendered inside an iframe with these globals already available:
32
+ - React, ReactDOM (via CDN)
33
+ - Tailwind CSS (via CDN)
34
+ - Recharts (for charts/graphs)
35
+ - Three.js + @react-three/fiber (for 3D)
36
+ - Framer Motion (for animations)
37
+ - GSAP (for complex animations)
38
+ - Lucide React (for icons)
39
+
40
+ ## Component Pattern
41
+ Write a single default export function component:
42
+ \`\`\`
43
+ export default function Creation() {
44
+ // Use React.useState, React.useEffect etc.
45
+ return <div>...</div>;
46
+ }
47
+ \`\`\`
48
+
49
+ ## Data Access
50
+ The component receives store data via the useStore hook:
51
+ \`\`\`
52
+ const { products, store, categories } = useStore();
53
+ \`\`\`
54
+
55
+ Product shape:
56
+ { id, name, sku, description, short_description, status, type,
57
+ cost_price, wholesale_price, stock_quantity, featured,
58
+ field_values: { thca_percentage, strain_type, terpenes, effects, cbd_total, ... },
59
+ pricing_data: { mode, tiers: [{ label, quantity, unit, price }] },
60
+ category: { id, name } }
61
+
62
+ Store shape:
63
+ { name, logo_url, primary_color, secondary_color }
64
+
65
+ ## Design Conventions
66
+ - Dark theme by default (bg-gray-900/950, text-white)
67
+ - Use Tailwind utility classes
68
+ - Responsive design with grid/flex layouts
69
+ - Smooth animations with Framer Motion or CSS transitions
70
+ - Professional typography with clear hierarchy
71
+ - Brand colors from store.primary_color / store.secondary_color when available
72
+
73
+ ## Types of Creations
74
+ - display: Full-screen menu display for TV monitors, auto-rotating categories
75
+ - landing: Marketing/promotional landing page
76
+ - dashboard: Analytics or status display
77
+ - component: Reusable UI component
78
+ - artifact: Standalone interactive piece`;
79
+ // ============================================================================
80
+ // HANDLER
81
+ // ============================================================================
82
+ export async function handleCreations(sb, args, storeId) {
83
+ const sid = storeId;
84
+ const action = args.action;
85
+ switch (action) {
86
+ // ================================================================
87
+ // FIND — search/list creations
88
+ // ================================================================
89
+ case "find": {
90
+ const limit = Math.min(args.limit || 25, 100);
91
+ let q = sb
92
+ .from("creations")
93
+ .select(CREATION_LIST_COLS)
94
+ .eq("store_id", sid)
95
+ .order("updated_at", { ascending: false })
96
+ .limit(limit);
97
+ if (args.query) {
98
+ const sq = sanitizeFilterValue(String(args.query));
99
+ q = q.or(`name.ilike.%${sq}%,slug.ilike.%${sq}%`);
100
+ }
101
+ if (args.creation_type)
102
+ q = q.eq("creation_type", args.creation_type);
103
+ if (args.status)
104
+ q = q.eq("status", args.status);
105
+ if (args.location_id)
106
+ q = q.eq("location_id", args.location_id);
107
+ if (args.visibility)
108
+ q = q.eq("visibility", args.visibility);
109
+ const { data, error } = await q;
110
+ if (error)
111
+ return { success: false, error: error.message };
112
+ return { success: true, data: { count: data?.length || 0, creations: data } };
113
+ }
114
+ // ================================================================
115
+ // GET — full creation details with code + collections
116
+ // ================================================================
117
+ case "get": {
118
+ const creationId = args.creation_id;
119
+ if (!creationId)
120
+ return { success: false, error: "creation_id is required" };
121
+ const { data: creation, error } = await sb
122
+ .from("creations")
123
+ .select(CREATION_FULL_COLS)
124
+ .eq("id", creationId)
125
+ .eq("store_id", sid)
126
+ .single();
127
+ if (error)
128
+ return { success: false, error: error.message };
129
+ // Fetch collection memberships
130
+ const { data: memberships } = await sb
131
+ .from("creation_collection_items")
132
+ .select("id, collection_id, position, label, collection:creation_collections!collection_id(id, name)")
133
+ .eq("creation_id", creationId);
134
+ return {
135
+ success: true,
136
+ data: {
137
+ ...creation,
138
+ collections: memberships?.map((m) => ({
139
+ item_id: m.id,
140
+ collection_id: m.collection_id,
141
+ collection_name: m.collection?.name,
142
+ position: m.position,
143
+ label: m.label,
144
+ })) || [],
145
+ storefront_url: `${STOREFRONT_URL}/creations/${creation.slug || creation.id}`,
146
+ },
147
+ };
148
+ }
149
+ // ================================================================
150
+ // CREATE — manual creation with code
151
+ // ================================================================
152
+ case "create": {
153
+ const name = args.name;
154
+ if (!name)
155
+ return { success: false, error: "name is required" };
156
+ const insert = {
157
+ store_id: sid,
158
+ name,
159
+ slug: args.slug || slugify(name),
160
+ creation_type: args.creation_type || "display",
161
+ status: args.status || "draft",
162
+ };
163
+ if (args.react_code)
164
+ insert.react_code = args.react_code;
165
+ if (args.description)
166
+ insert.description = args.description;
167
+ if (args.display_mode)
168
+ insert.display_mode = args.display_mode;
169
+ if (args.visibility)
170
+ insert.visibility = args.visibility;
171
+ if (args.location_id)
172
+ insert.location_id = args.location_id;
173
+ if (args.data_config)
174
+ insert.data_config = args.data_config;
175
+ if (args.theme_config)
176
+ insert.theme_config = args.theme_config;
177
+ if (args.layout_config)
178
+ insert.layout_config = args.layout_config;
179
+ if (args.thumbnail_url)
180
+ insert.thumbnail_url = args.thumbnail_url;
181
+ const { data, error } = await sb
182
+ .from("creations")
183
+ .insert(insert)
184
+ .select(CREATION_LIST_COLS)
185
+ .single();
186
+ if (error)
187
+ return { success: false, error: error.message };
188
+ return {
189
+ success: true,
190
+ data: {
191
+ ...data,
192
+ storefront_url: `${STOREFRONT_URL}/creations/${data.slug || data.id}`,
193
+ },
194
+ };
195
+ }
196
+ // ================================================================
197
+ // UPDATE — modify any fields
198
+ // ================================================================
199
+ case "update": {
200
+ const creationId = args.creation_id;
201
+ if (!creationId)
202
+ return { success: false, error: "creation_id is required" };
203
+ const update = { updated_at: new Date().toISOString() };
204
+ if (args.name !== undefined)
205
+ update.name = args.name;
206
+ if (args.react_code !== undefined)
207
+ update.react_code = args.react_code;
208
+ if (args.description !== undefined)
209
+ update.description = args.description;
210
+ if (args.creation_type !== undefined)
211
+ update.creation_type = args.creation_type;
212
+ if (args.status !== undefined)
213
+ update.status = args.status;
214
+ if (args.slug !== undefined)
215
+ update.slug = args.slug;
216
+ if (args.display_mode !== undefined)
217
+ update.display_mode = args.display_mode;
218
+ if (args.visibility !== undefined)
219
+ update.visibility = args.visibility;
220
+ if (args.location_id !== undefined)
221
+ update.location_id = args.location_id;
222
+ if (args.data_config !== undefined)
223
+ update.data_config = args.data_config;
224
+ if (args.theme_config !== undefined)
225
+ update.theme_config = args.theme_config;
226
+ if (args.layout_config !== undefined)
227
+ update.layout_config = args.layout_config;
228
+ if (args.thumbnail_url !== undefined)
229
+ update.thumbnail_url = args.thumbnail_url;
230
+ const { data, error } = await sb
231
+ .from("creations")
232
+ .update(update)
233
+ .eq("id", creationId)
234
+ .eq("store_id", sid)
235
+ .select(CREATION_LIST_COLS)
236
+ .single();
237
+ if (error)
238
+ return { success: false, error: error.message };
239
+ return { success: true, data };
240
+ }
241
+ // ================================================================
242
+ // DELETE — archive (default) or hard delete
243
+ // ================================================================
244
+ case "delete": {
245
+ const creationId = args.creation_id;
246
+ if (!creationId)
247
+ return { success: false, error: "creation_id is required" };
248
+ const hard = args.hard === true;
249
+ if (hard) {
250
+ // Remove collection memberships first
251
+ await sb
252
+ .from("creation_collection_items")
253
+ .delete()
254
+ .eq("creation_id", creationId);
255
+ const { error } = await sb
256
+ .from("creations")
257
+ .delete()
258
+ .eq("id", creationId)
259
+ .eq("store_id", sid);
260
+ if (error)
261
+ return { success: false, error: error.message };
262
+ return { success: true, data: { deleted: creationId, hard: true } };
263
+ }
264
+ const { error } = await sb
265
+ .from("creations")
266
+ .update({ status: "archived", updated_at: new Date().toISOString() })
267
+ .eq("id", creationId)
268
+ .eq("store_id", sid);
269
+ if (error)
270
+ return { success: false, error: error.message };
271
+ return { success: true, data: { archived: creationId } };
272
+ }
273
+ // ================================================================
274
+ // DUPLICATE — clone an existing creation
275
+ // ================================================================
276
+ case "duplicate": {
277
+ const creationId = args.creation_id;
278
+ if (!creationId)
279
+ return { success: false, error: "creation_id is required" };
280
+ const { data: original, error: fetchErr } = await sb
281
+ .from("creations")
282
+ .select(CREATION_FULL_COLS)
283
+ .eq("id", creationId)
284
+ .eq("store_id", sid)
285
+ .single();
286
+ if (fetchErr)
287
+ return { success: false, error: fetchErr.message };
288
+ const newName = args.name || `${original.name} (copy)`;
289
+ const { data: clone, error: insertErr } = await sb
290
+ .from("creations")
291
+ .insert({
292
+ store_id: sid,
293
+ name: newName,
294
+ slug: slugify(newName),
295
+ creation_type: original.creation_type,
296
+ status: "draft",
297
+ display_mode: original.display_mode,
298
+ visibility: original.visibility,
299
+ description: original.description,
300
+ react_code: original.react_code,
301
+ data_config: original.data_config,
302
+ theme_config: original.theme_config,
303
+ layout_config: original.layout_config,
304
+ })
305
+ .select(CREATION_LIST_COLS)
306
+ .single();
307
+ if (insertErr)
308
+ return { success: false, error: insertErr.message };
309
+ return {
310
+ success: true,
311
+ data: {
312
+ ...clone,
313
+ cloned_from: creationId,
314
+ storefront_url: `${STOREFRONT_URL}/creations/${clone.slug || clone.id}`,
315
+ },
316
+ };
317
+ }
318
+ // ================================================================
319
+ // GENERATE — AI-powered creation from prompt
320
+ // ================================================================
321
+ case "generate": {
322
+ const prompt = args.prompt;
323
+ if (!prompt)
324
+ return { success: false, error: "prompt is required" };
325
+ const creationType = args.creation_type || "display";
326
+ const name = args.name || `AI: ${prompt.substring(0, 60)}`;
327
+ // Generate React code via LLM handler
328
+ const llmResult = await handleLLM(sb, {
329
+ action: "complete",
330
+ prompt: `Create a ${creationType} React component for: ${prompt}`,
331
+ system: GENERATION_SYSTEM_PROMPT,
332
+ provider: "anthropic",
333
+ model: MODELS.SONNET,
334
+ max_tokens: 8192,
335
+ temperature: 0.7,
336
+ }, storeId);
337
+ if (!llmResult.success) {
338
+ return { success: false, error: `Code generation failed: ${llmResult.error}` };
339
+ }
340
+ const llmData = llmResult.data;
341
+ let reactCode = llmData.text;
342
+ // Strip markdown code fences if present
343
+ reactCode = reactCode
344
+ .replace(/^```(?:jsx?|tsx?|react)?\s*\n?/m, "")
345
+ .replace(/\n?```\s*$/m, "")
346
+ .trim();
347
+ // Save as draft creation
348
+ const { data: creation, error: createErr } = await sb
349
+ .from("creations")
350
+ .insert({
351
+ store_id: sid,
352
+ name,
353
+ slug: slugify(name),
354
+ creation_type: creationType,
355
+ status: "draft",
356
+ react_code: reactCode,
357
+ description: `AI-generated from prompt: ${prompt}`,
358
+ })
359
+ .select(CREATION_LIST_COLS)
360
+ .single();
361
+ if (createErr)
362
+ return { success: false, error: createErr.message };
363
+ return {
364
+ success: true,
365
+ data: {
366
+ ...creation,
367
+ storefront_url: `${STOREFRONT_URL}/creations/${creation.slug || creation.id}`,
368
+ tokens_used: llmData.tokens,
369
+ code_length: reactCode.length,
370
+ },
371
+ };
372
+ }
373
+ // ================================================================
374
+ // ADD_TO_COLLECTION — link creation to a collection
375
+ // ================================================================
376
+ case "add_to_collection": {
377
+ const creationId = args.creation_id;
378
+ const collectionId = args.collection_id;
379
+ if (!creationId || !collectionId) {
380
+ return { success: false, error: "creation_id and collection_id are required" };
381
+ }
382
+ const insert = {
383
+ creation_id: creationId,
384
+ collection_id: collectionId,
385
+ };
386
+ if (args.position !== undefined)
387
+ insert.position = args.position;
388
+ if (args.label)
389
+ insert.label = args.label;
390
+ const { data, error } = await sb
391
+ .from("creation_collection_items")
392
+ .insert(insert)
393
+ .select("id, creation_id, collection_id, position, label")
394
+ .single();
395
+ if (error)
396
+ return { success: false, error: error.message };
397
+ return { success: true, data };
398
+ }
399
+ // ================================================================
400
+ // REMOVE_FROM_COLLECTION — unlink creation from a collection
401
+ // ================================================================
402
+ case "remove_from_collection": {
403
+ const creationId = args.creation_id;
404
+ const collectionId = args.collection_id;
405
+ if (!creationId || !collectionId) {
406
+ return { success: false, error: "creation_id and collection_id are required" };
407
+ }
408
+ const { error } = await sb
409
+ .from("creation_collection_items")
410
+ .delete()
411
+ .eq("creation_id", creationId)
412
+ .eq("collection_id", collectionId);
413
+ if (error)
414
+ return { success: false, error: error.message };
415
+ return { success: true, data: { removed: true, creation_id: creationId, collection_id: collectionId } };
416
+ }
417
+ // ================================================================
418
+ // PREVIEW — screenshot via Playwright, upload as thumbnail
419
+ // ================================================================
420
+ case "preview": {
421
+ const creationId = args.creation_id;
422
+ if (!creationId)
423
+ return { success: false, error: "creation_id is required" };
424
+ // Get creation to build URL
425
+ const { data: creation, error: fetchErr } = await sb
426
+ .from("creations")
427
+ .select("id, slug, name")
428
+ .eq("id", creationId)
429
+ .eq("store_id", sid)
430
+ .single();
431
+ if (fetchErr)
432
+ return { success: false, error: fetchErr.message };
433
+ const previewUrl = `${STOREFRONT_URL}/creations/${creation.slug || creation.id}`;
434
+ // Take screenshot via browser handler
435
+ const browserResult = await handleBrowser(sb, {
436
+ action: "screenshot",
437
+ url: previewUrl,
438
+ }, storeId);
439
+ if (!browserResult.success) {
440
+ return { success: false, error: `Screenshot failed: ${browserResult.error}` };
441
+ }
442
+ const screenshotData = browserResult.data;
443
+ // Upload to Supabase storage
444
+ const fileName = `creation-${creationId}.png`;
445
+ const storagePath = `creations/${sid}/${fileName}`;
446
+ const buffer = Buffer.from(screenshotData.screenshot_base64, "base64");
447
+ const { error: uploadErr } = await sb.storage
448
+ .from("product-images")
449
+ .upload(storagePath, buffer, {
450
+ contentType: "image/png",
451
+ upsert: true,
452
+ });
453
+ if (uploadErr) {
454
+ return { success: false, error: `Upload failed: ${uploadErr.message}` };
455
+ }
456
+ const { data: urlData } = sb.storage.from("product-images").getPublicUrl(storagePath);
457
+ const thumbnailUrl = urlData.publicUrl;
458
+ // Update creation with thumbnail
459
+ await sb
460
+ .from("creations")
461
+ .update({ thumbnail_url: thumbnailUrl, updated_at: new Date().toISOString() })
462
+ .eq("id", creationId)
463
+ .eq("store_id", sid);
464
+ return {
465
+ success: true,
466
+ data: {
467
+ creation_id: creationId,
468
+ thumbnail_url: thumbnailUrl,
469
+ size_bytes: buffer.length,
470
+ },
471
+ };
472
+ }
473
+ default:
474
+ return {
475
+ success: false,
476
+ error: `Unknown creations action: ${action}. Valid: find, get, create, update, delete, duplicate, generate, add_to_collection, remove_from_collection, preview`,
477
+ };
478
+ }
479
+ }
@@ -0,0 +1,89 @@
1
+ import type { SupabaseClient } from "@supabase/supabase-js";
2
+ export declare function handleCustomers(sb: SupabaseClient, args: Record<string, unknown>, storeId?: string): Promise<{
3
+ success: boolean;
4
+ error: string;
5
+ count?: undefined;
6
+ data?: undefined;
7
+ note?: undefined;
8
+ linked?: undefined;
9
+ } | {
10
+ success: boolean;
11
+ count: number;
12
+ data: {
13
+ id: any;
14
+ platform_user_id: any;
15
+ first_name: any;
16
+ last_name: any;
17
+ email: any;
18
+ phone: any;
19
+ loyalty_points: any;
20
+ loyalty_tier: any;
21
+ total_spent: any;
22
+ total_orders: any;
23
+ lifetime_value: any;
24
+ is_active: any;
25
+ created_at: any;
26
+ }[];
27
+ error?: undefined;
28
+ note?: undefined;
29
+ linked?: undefined;
30
+ } | {
31
+ success: boolean;
32
+ data: any;
33
+ error?: undefined;
34
+ count?: undefined;
35
+ note?: undefined;
36
+ linked?: undefined;
37
+ } | {
38
+ success: boolean;
39
+ data: any;
40
+ note: string;
41
+ error?: undefined;
42
+ count?: undefined;
43
+ linked?: undefined;
44
+ } | {
45
+ success: boolean;
46
+ count: number;
47
+ data: {
48
+ id: any;
49
+ order_number: any;
50
+ status: any;
51
+ total_amount: any;
52
+ subtotal: any;
53
+ tax_amount: any;
54
+ payment_status: any;
55
+ fulfillment_status: any;
56
+ payment_method: any;
57
+ created_at: any;
58
+ }[];
59
+ error?: undefined;
60
+ note?: undefined;
61
+ linked?: undefined;
62
+ } | {
63
+ success: boolean;
64
+ linked: {
65
+ customer_id: string;
66
+ channel_type: string;
67
+ sender_id: string;
68
+ };
69
+ error?: undefined;
70
+ count?: undefined;
71
+ data?: undefined;
72
+ note?: undefined;
73
+ }>;
74
+ export declare function handleOrders(sb: SupabaseClient, args: Record<string, unknown>, storeId?: string): Promise<{
75
+ success: boolean;
76
+ error: string;
77
+ count?: undefined;
78
+ data?: undefined;
79
+ } | {
80
+ success: boolean;
81
+ count: number;
82
+ data: any[];
83
+ error?: undefined;
84
+ } | {
85
+ success: boolean;
86
+ data: any;
87
+ error?: undefined;
88
+ count?: undefined;
89
+ }>;