windmill-components 1.677.0 → 1.687.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 (358) hide show
  1. package/package/components/AppConnectInner.svelte +6 -0
  2. package/package/components/CiTestResults.svelte +64 -0
  3. package/package/components/CiTestResults.svelte.d.ts +7 -0
  4. package/package/components/CompareWorkspaces.svelte +626 -418
  5. package/package/components/DBManager.svelte +35 -4
  6. package/package/components/DBManager.svelte.d.ts +2 -0
  7. package/package/components/DBManagerContent.svelte +3 -1
  8. package/package/components/DBManagerContent.svelte.d.ts +3 -0
  9. package/package/components/DBManagerDrawer.svelte +145 -3
  10. package/package/components/DBTableEditor.svelte +14 -4
  11. package/package/components/DatatablePicker.svelte +2 -5
  12. package/package/components/DatatableSchemaDiff.svelte +531 -0
  13. package/package/components/DatatableSchemaDiff.svelte.d.ts +29 -0
  14. package/package/components/DedicatedWorkersSelector.svelte +4 -2
  15. package/package/components/DefaultTagsInner.svelte +42 -2
  16. package/package/components/DeployWorkspaceDrawer.svelte +1 -1
  17. package/package/components/Dev.svelte +20 -3
  18. package/package/components/Editor.svelte +1 -1
  19. package/package/components/EditorBar.svelte +1 -1
  20. package/package/components/EditorBar.svelte.d.ts +1 -1
  21. package/package/components/FlowStatusViewerInner.svelte +269 -220
  22. package/package/components/FlowTimeline.svelte +1 -1
  23. package/package/components/FolderEditor.svelte +189 -4
  24. package/package/components/ForkWorkspaceBanner.svelte +82 -11
  25. package/package/components/GlobalUserOffboardingModal.svelte +293 -0
  26. package/package/components/GlobalUserOffboardingModal.svelte.d.ts +10 -0
  27. package/package/components/InstanceSettings.svelte +22 -3
  28. package/package/components/Login.svelte +22 -10
  29. package/package/components/ModuleTest.svelte +2 -1
  30. package/package/components/NoMainFuncBadge.svelte +1 -1
  31. package/package/components/OffboardItemsBox.svelte +56 -0
  32. package/package/components/OffboardItemsBox.svelte.d.ts +12 -0
  33. package/package/components/OffboardReassignControls.svelte +47 -0
  34. package/package/components/OffboardReassignControls.svelte.d.ts +20 -0
  35. package/package/components/OffboardWorkspaceSection.svelte +110 -0
  36. package/package/components/OffboardWorkspaceSection.svelte.d.ts +24 -0
  37. package/package/components/OnBehalfOfSelector.svelte +21 -3
  38. package/package/components/OnBehalfOfSelector.svelte.d.ts +7 -0
  39. package/package/components/QueueAlerts.svelte +10 -10
  40. package/package/components/ResourcePicker.svelte +2 -2
  41. package/package/components/ScriptBuilder.svelte +52 -11
  42. package/package/components/ScriptEditor.svelte +1 -3
  43. package/package/components/ScriptEditor.svelte.d.ts +1 -1
  44. package/package/components/ShareModal.svelte +236 -98
  45. package/package/components/SuperadminSettingsInner.svelte +362 -315
  46. package/package/components/UserOffboardingModal.svelte +238 -0
  47. package/package/components/UserOffboardingModal.svelte.d.ts +10 -0
  48. package/package/components/WorkspaceDeployLayout.svelte +3 -3
  49. package/package/components/WorkspaceDeployLayout.svelte.d.ts +1 -0
  50. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptRunnableByPath.svelte +4 -2
  51. package/package/components/apps/editor/settingsPanel/mainInput/RunnableSelector.svelte +12 -0
  52. package/package/components/assets/AssetsDropdownButton.svelte +1 -1
  53. package/package/components/common/confirmationModal/ConfirmationModal.svelte +1 -1
  54. package/package/components/common/table/AppRow.svelte +3 -3
  55. package/package/components/common/table/FlowRow.svelte +3 -3
  56. package/package/components/common/table/RawAppRow.svelte +4 -4
  57. package/package/components/common/table/Row.svelte +6 -2
  58. package/package/components/common/table/ScriptRow.svelte +11 -3
  59. package/package/components/copilot/chat/AIChatManager.svelte.js +2 -2
  60. package/package/components/copilot/chat/anthropic.d.ts +7 -1
  61. package/package/components/copilot/chat/anthropic.js +5 -2
  62. package/package/components/copilot/chat/app/core.js +129 -1
  63. package/package/components/copilot/chat/app/core.test.js +192 -0
  64. package/package/components/copilot/chat/chatLoop.d.ts +3 -0
  65. package/package/components/copilot/chat/chatLoop.js +13 -5
  66. package/package/components/copilot/chat/flow/FlowAIChat.svelte +55 -76
  67. package/package/components/copilot/chat/flow/core.d.ts +13 -3
  68. package/package/components/copilot/chat/flow/core.js +467 -116
  69. package/package/components/copilot/chat/flow/helperUtils.d.ts +19 -0
  70. package/package/components/copilot/chat/flow/helperUtils.js +68 -0
  71. package/package/components/copilot/chat/flow/helperUtils.test.js +116 -0
  72. package/package/components/copilot/chat/flow/inlineScriptsUtils.d.ts +5 -24
  73. package/package/components/copilot/chat/flow/inlineScriptsUtils.js +30 -55
  74. package/package/components/copilot/chat/flow/utils.test.js +59 -0
  75. package/package/components/copilot/chat/openai-responses.d.ts +7 -1
  76. package/package/components/copilot/chat/openai-responses.js +5 -2
  77. package/package/components/copilot/chat/shared.d.ts +1 -2
  78. package/package/components/copilot/chat/shared.js +94 -52
  79. package/package/components/copilot/chat/tokenUsage.d.ts +23 -0
  80. package/package/components/copilot/chat/tokenUsage.js +42 -0
  81. package/package/components/copilot/lib.d.ts +5 -1
  82. package/package/components/copilot/lib.js +21 -5
  83. package/package/components/deploymentRequest/DeploymentRequestPanel.svelte +337 -0
  84. package/package/components/deploymentRequest/DeploymentRequestPanel.svelte.d.ts +15 -0
  85. package/package/components/details/CopyableCodeBlock.svelte +18 -8
  86. package/package/components/details/CopyableCodeBlock.svelte.d.ts +1 -0
  87. package/package/components/flows/FlowAssetsHandler.svelte +19 -21
  88. package/package/components/flows/agentToolTree.d.ts +17 -0
  89. package/package/components/flows/agentToolTree.js +114 -0
  90. package/package/components/flows/agentToolTree.test.d.ts +1 -0
  91. package/package/components/flows/agentToolTree.test.js +86 -0
  92. package/package/components/flows/agentToolUtils.d.ts +0 -5
  93. package/package/components/flows/agentToolUtils.js +0 -49
  94. package/package/components/flows/content/FlowLoop.svelte +7 -4
  95. package/package/components/flows/content/FlowModuleDeleteAfterUse.svelte +15 -7
  96. package/package/components/flows/content/FlowSettings.svelte +29 -0
  97. package/package/components/flows/dfs.d.ts +6 -2
  98. package/package/components/flows/dfs.js +19 -11
  99. package/package/components/flows/flowDeleteController.d.ts +32 -0
  100. package/package/components/flows/flowDeleteController.js +54 -0
  101. package/package/components/flows/flowDeleteController.test.d.ts +1 -0
  102. package/package/components/flows/flowDeleteController.test.js +121 -0
  103. package/package/components/flows/flowDeleteUtils.d.ts +48 -0
  104. package/package/components/flows/flowDeleteUtils.js +150 -0
  105. package/package/components/flows/flowDeleteUtils.test.d.ts +1 -0
  106. package/package/components/flows/flowDeleteUtils.test.js +131 -0
  107. package/package/components/flows/flowDiff.d.ts +2 -47
  108. package/package/components/flows/flowDiff.js +16 -293
  109. package/package/components/flows/flowDiff.testUtils.d.ts +8 -0
  110. package/package/components/flows/flowDiff.testUtils.js +26 -0
  111. package/package/components/flows/flowDiffManager.svelte.js +20 -75
  112. package/package/components/flows/flowDiffManager.svelte.test.js +103 -2
  113. package/package/components/flows/flowExplorer.d.ts +4 -0
  114. package/package/components/flows/flowExplorer.js +7 -30
  115. package/package/components/flows/flowState.d.ts +1 -0
  116. package/package/components/flows/flowStateUtils.svelte.js +6 -1
  117. package/package/components/flows/flowStore.svelte.d.ts +1 -1
  118. package/package/components/flows/flowTree.d.ts +91 -0
  119. package/package/components/flows/flowTree.js +326 -0
  120. package/package/components/flows/flowTree.test.d.ts +1 -0
  121. package/package/components/flows/flowTree.test.js +236 -0
  122. package/package/components/flows/map/FlowJobsMenu.svelte +36 -30
  123. package/package/components/flows/map/FlowModuleSchemaItem.svelte +1 -1
  124. package/package/components/flows/map/FlowModuleSchemaMap.svelte +70 -227
  125. package/package/components/flows/map/FlowModuleSchemaMap.svelte.d.ts +0 -2
  126. package/package/components/flows/pickers/PickHubScriptQuick.svelte +2 -2
  127. package/package/components/flows/pickers/PickHubScriptQuick.svelte.d.ts +1 -1
  128. package/package/components/flows/previousResults.js +13 -41
  129. package/package/components/flows/previousResults.test.d.ts +1 -0
  130. package/package/components/flows/previousResults.test.js +65 -0
  131. package/package/components/flows/propPicker/OutputPicker.svelte +2 -1
  132. package/package/components/flows/propPicker/OutputPickerInner.svelte +41 -4
  133. package/package/components/flows/propPicker/StepHistory.svelte +9 -1
  134. package/package/components/git_sync/GitSyncContext.svelte.js +11 -5
  135. package/package/components/git_sync/GitSyncRepositoryCard.svelte +2 -29
  136. package/package/components/git_sync/PullWorkspaceModal.svelte +6 -7
  137. package/package/components/graph/FlowGraphV2.svelte +2 -2
  138. package/package/components/graph/FlowGraphV2.svelte.d.ts +1 -0
  139. package/package/components/graph/groupedModulesProxy.svelte.d.ts +10 -0
  140. package/package/components/graph/groupedModulesProxy.svelte.js +17 -1
  141. package/package/components/graph/renderers/triggers/TriggersBadge.svelte +5 -2
  142. package/package/components/home/HomeConnectDrawer.svelte +125 -0
  143. package/package/components/home/HomeConnectDrawer.svelte.d.ts +5 -0
  144. package/package/components/icons/GithubIcon.svelte +4 -4
  145. package/package/components/icons/GithubIcon.svelte.d.ts +5 -2
  146. package/package/components/instanceSettings/ExternalJwtTokens.svelte +85 -0
  147. package/package/components/instanceSettings/ExternalJwtTokens.svelte.d.ts +12 -0
  148. package/package/components/instanceSettings/GhesAppSettings.svelte +17 -0
  149. package/package/components/instanceSettings/IndexerMemorySettings.svelte +56 -29
  150. package/package/components/instanceSettings/SecretBackendConfig.svelte +9 -2
  151. package/package/components/instanceSettings.d.ts +1 -0
  152. package/package/components/instanceSettings.js +42 -8
  153. package/package/components/offboarding-utils.d.ts +11 -0
  154. package/package/components/offboarding-utils.js +100 -0
  155. package/package/components/raw_apps/RawAppDataTableDrawer.svelte +1 -1
  156. package/package/components/raw_apps/RawAppEditor.svelte +27 -0
  157. package/package/components/raw_apps/RawAppEditorHeader.svelte +6 -1
  158. package/package/components/raw_apps/RawAppEditorHeader.svelte.d.ts +1 -0
  159. package/package/components/raw_apps/RawAppYamlEditor.svelte +81 -0
  160. package/package/components/raw_apps/RawAppYamlEditor.svelte.d.ts +20 -0
  161. package/package/components/raw_apps/datatableUtils.svelte.js +1 -1
  162. package/package/components/runs/runsFilter.d.ts +1 -1
  163. package/package/components/script_builder.d.ts +1 -1
  164. package/package/components/select/Select.svelte +2 -1
  165. package/package/components/select/Select.svelte.d.ts +1 -0
  166. package/package/components/settings/CreateToken.svelte +113 -64
  167. package/package/components/settings/CreateToken.svelte.d.ts +3 -0
  168. package/package/components/settings/WorkspaceUserSettings.svelte +34 -28
  169. package/package/components/sidebar/SidebarContent.svelte +58 -2
  170. package/package/components/sidebar/WorkspaceMenu.svelte +8 -4
  171. package/package/components/triggers/AddTriggersButton.svelte +11 -0
  172. package/package/components/triggers/PermissionedAsLine.svelte +37 -3
  173. package/package/components/triggers/PermissionedAsLine.svelte.d.ts +6 -0
  174. package/package/components/triggers/TriggersEditor.svelte +5 -1
  175. package/package/components/triggers/TriggersWrapper.svelte +10 -0
  176. package/package/components/triggers/email/EmailTriggerEditorInner.svelte +13 -11
  177. package/package/components/triggers/gcp/GcpTriggerEditorInner.svelte +13 -11
  178. package/package/components/triggers/http/RouteEditorConfigSection.svelte +15 -7
  179. package/package/components/triggers/http/RouteEditorInner.svelte +14 -14
  180. package/package/components/triggers/http/RoutesGenerator.svelte +6 -1
  181. package/package/components/triggers/http/RoutesPanel.svelte +1 -1
  182. package/package/components/triggers/http/utils.d.ts +1 -1
  183. package/package/components/triggers/http/utils.js +2 -2
  184. package/package/components/triggers/kafka/KafkaTriggerEditorInner.svelte +13 -11
  185. package/package/components/triggers/mqtt/MqttEditorConfigSection.svelte.d.ts +1 -1
  186. package/package/components/triggers/mqtt/MqttTriggerEditorInner.svelte +13 -11
  187. package/package/components/triggers/native/NativeTriggerEditor.svelte +3 -0
  188. package/package/components/triggers/native/services/github/GitHubTriggerForm.svelte +118 -0
  189. package/package/components/triggers/native/services/github/GitHubTriggerForm.svelte.d.ts +17 -0
  190. package/package/components/triggers/native/utils.js +14 -0
  191. package/package/components/triggers/nats/NatsTriggerEditor.svelte.d.ts +4 -3
  192. package/package/components/triggers/nats/NatsTriggerEditorInner.svelte +13 -11
  193. package/package/components/triggers/postgres/PostgresTriggerEditor.svelte.d.ts +4 -3
  194. package/package/components/triggers/postgres/PostgresTriggerEditorInner.svelte +13 -11
  195. package/package/components/triggers/schedules/ScheduleEditorInner.svelte +13 -11
  196. package/package/components/triggers/sqs/SqsTriggerEditor.svelte.d.ts +4 -3
  197. package/package/components/triggers/sqs/SqsTriggerEditorInner.svelte +13 -11
  198. package/package/components/triggers/triggers.svelte.js +1 -0
  199. package/package/components/triggers/utils.js +27 -6
  200. package/package/components/triggers/websocket/WebsocketTriggerEditorInner.svelte +13 -11
  201. package/package/components/triggers.d.ts +1 -1
  202. package/package/components/useFolderDefaultPermissionedAs.svelte.d.ts +13 -0
  203. package/package/components/useFolderDefaultPermissionedAs.svelte.js +63 -0
  204. package/package/components/workspaceSettings/CreateWorkspace.svelte +16 -677
  205. package/package/components/workspaceSettings/CreateWorkspaceInner.svelte +604 -0
  206. package/package/components/workspaceSettings/CreateWorkspaceInner.svelte.d.ts +7 -0
  207. package/package/components/workspaceSettings/CustomInstanceDbSelect.svelte +27 -25
  208. package/package/components/workspaceSettings/CustomInstanceDbWizardModal.svelte +46 -8
  209. package/package/components/workspaceSettings/DataTableSettings.svelte +27 -22
  210. package/package/components/workspaceSettings/DucklakeSettings.svelte +1 -1
  211. package/package/components/workspaceSettings/ForkDatatableSection.svelte +228 -0
  212. package/package/components/workspaceSettings/ForkDatatableSection.svelte.d.ts +28 -0
  213. package/package/components/workspaceSettings/GitSyncFilterSettings.svelte +8 -2
  214. package/package/components/workspaceSettings/RulesetEditor.svelte +27 -2
  215. package/package/components/workspaceSettings/VolumeStorageSettings.svelte +1 -1
  216. package/package/components/workspaceSettings/WorkspaceIntegrations.svelte +17 -1
  217. package/package/consts.d.ts +3 -0
  218. package/package/consts.js +10 -0
  219. package/package/gen/core/OpenAPI.js +1 -1
  220. package/package/gen/schemas.gen.d.ts +1172 -164
  221. package/package/gen/schemas.gen.js +1168 -157
  222. package/package/gen/services.gen.d.ts +511 -6
  223. package/package/gen/services.gen.js +1023 -23
  224. package/package/gen/types.gen.d.ts +2278 -151
  225. package/package/githubApp.js +5 -1
  226. package/package/hubPaths.json +1 -4
  227. package/package/infer.js +13 -1
  228. package/package/infer.svelte.js +10 -1
  229. package/package/monaco_workers/sqlTypePlugin.worker.d.ts +10 -0
  230. package/package/monaco_workers/sqlTypePlugin.worker.js +39 -0
  231. package/package/script_helpers.d.ts +8 -2
  232. package/package/script_helpers.js +14 -0
  233. package/package/stores.d.ts +4 -0
  234. package/package/stores.js +1 -0
  235. package/package/system_prompts/prompts.d.ts +4 -3
  236. package/package/system_prompts/prompts.js +270 -20
  237. package/package/templates/ci_test_bun.ts.template +19 -0
  238. package/package/templates/ci_test_python.py.template +18 -0
  239. package/package/utils_deployable.d.ts +11 -7
  240. package/package/utils_workspace_deploy.d.ts +8 -8
  241. package/package/utils_workspace_deploy.js +86 -420
  242. package/package.json +4 -4
  243. package/package/components/copilot/chat/__tests__/app/appChat.eval.test.js +0 -153
  244. package/package/components/copilot/chat/__tests__/app/appEvalComparison.d.ts +0 -21
  245. package/package/components/copilot/chat/__tests__/app/appEvalComparison.js +0 -136
  246. package/package/components/copilot/chat/__tests__/app/appEvalHelpers.d.ts +0 -15
  247. package/package/components/copilot/chat/__tests__/app/appEvalHelpers.js +0 -107
  248. package/package/components/copilot/chat/__tests__/app/appEvalRunner.d.ts +0 -50
  249. package/package/components/copilot/chat/__tests__/app/appEvalRunner.js +0 -93
  250. package/package/components/copilot/chat/__tests__/app/appFixtureLoader.d.ts +0 -29
  251. package/package/components/copilot/chat/__tests__/app/appFixtureLoader.js +0 -134
  252. package/package/components/copilot/chat/__tests__/app/appResultsWriter.d.ts +0 -30
  253. package/package/components/copilot/chat/__tests__/app/appResultsWriter.js +0 -197
  254. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/createFolder/main.d.ts +0 -10
  255. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/createFolder/main.js +0 -9
  256. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/createFolder/meta.json +0 -4
  257. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/deleteItem/main.d.ts +0 -6
  258. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/deleteItem/main.js +0 -5
  259. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/deleteItem/meta.json +0 -4
  260. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/listFiles/main.d.ts +0 -12
  261. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/listFiles/main.js +0 -14
  262. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/listFiles/meta.json +0 -4
  263. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/listFolders/main.d.ts +0 -8
  264. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/listFolders/main.js +0 -25
  265. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/listFolders/meta.json +0 -4
  266. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/moveItem/main.d.ts +0 -7
  267. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/moveItem/main.js +0 -5
  268. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/moveItem/meta.json +0 -4
  269. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/renameItem/main.d.ts +0 -8
  270. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/renameItem/main.js +0 -5
  271. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/renameItem/meta.json +0 -4
  272. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/Breadcrumb.d.ts +0 -10
  273. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/Breadcrumb.tsx +0 -26
  274. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/FileItem.d.ts +0 -10
  275. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/FileItem.tsx +0 -79
  276. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/FileList.d.ts +0 -10
  277. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/FileList.tsx +0 -46
  278. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/FolderTree.d.ts +0 -10
  279. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/FolderTree.tsx +0 -56
  280. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/Toolbar.d.ts +0 -6
  281. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/Toolbar.tsx +0 -59
  282. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/index.d.ts +0 -16
  283. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/index.tsx +0 -119
  284. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/addToCart/main.d.ts +0 -15
  285. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/addToCart/main.js +0 -14
  286. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/addToCart/meta.json +0 -4
  287. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/calculateTotal/main.d.ts +0 -14
  288. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/calculateTotal/main.js +0 -5
  289. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/calculateTotal/meta.json +0 -4
  290. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/getProducts/main.d.ts +0 -6
  291. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/getProducts/main.js +0 -41
  292. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/getProducts/meta.json +0 -4
  293. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/removeFromCart/main.d.ts +0 -15
  294. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/removeFromCart/main.js +0 -3
  295. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/removeFromCart/meta.json +0 -4
  296. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/components/Cart.d.ts +0 -9
  297. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/components/Cart.tsx +0 -51
  298. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/components/ProductCard.d.ts +0 -8
  299. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/components/ProductCard.tsx +0 -27
  300. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/components/ProductList.d.ts +0 -8
  301. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/components/ProductList.tsx +0 -18
  302. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/index.d.ts +0 -12
  303. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/index.tsx +0 -81
  304. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/backend/decrementCounter/main.d.ts +0 -3
  305. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/backend/decrementCounter/main.js +0 -3
  306. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/backend/decrementCounter/meta.json +0 -4
  307. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/backend/incrementCounter/main.d.ts +0 -3
  308. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/backend/incrementCounter/main.js +0 -3
  309. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/backend/incrementCounter/meta.json +0 -4
  310. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/frontend/index.d.ts +0 -2
  311. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/frontend/index.tsx +0 -38
  312. package/package/components/copilot/chat/__tests__/app/variants/baseline.d.ts +0 -6
  313. package/package/components/copilot/chat/__tests__/app/variants/baseline.js +0 -10
  314. package/package/components/copilot/chat/__tests__/app/variants/index.d.ts +0 -3
  315. package/package/components/copilot/chat/__tests__/app/variants/index.js +0 -3
  316. package/package/components/copilot/chat/__tests__/app/variants/streamlined.d.ts +0 -6
  317. package/package/components/copilot/chat/__tests__/app/variants/streamlined.js +0 -137
  318. package/package/components/copilot/chat/__tests__/flow/expected/test1.json +0 -134
  319. package/package/components/copilot/chat/__tests__/flow/expected/test2.json +0 -183
  320. package/package/components/copilot/chat/__tests__/flow/expected/test3.json +0 -204
  321. package/package/components/copilot/chat/__tests__/flow/expected/test4.json +0 -175
  322. package/package/components/copilot/chat/__tests__/flow/expected/test5_modify_simple.json +0 -68
  323. package/package/components/copilot/chat/__tests__/flow/expected/test6_modify_medium.json +0 -142
  324. package/package/components/copilot/chat/__tests__/flow/expected/test7_modify_complex.json +0 -136
  325. package/package/components/copilot/chat/__tests__/flow/flowChat.eval.test.js +0 -294
  326. package/package/components/copilot/chat/__tests__/flow/flowEvalComparison.d.ts +0 -17
  327. package/package/components/copilot/chat/__tests__/flow/flowEvalComparison.js +0 -49
  328. package/package/components/copilot/chat/__tests__/flow/flowEvalHelpers.d.ts +0 -12
  329. package/package/components/copilot/chat/__tests__/flow/flowEvalHelpers.js +0 -79
  330. package/package/components/copilot/chat/__tests__/flow/flowEvalRunner.d.ts +0 -50
  331. package/package/components/copilot/chat/__tests__/flow/flowEvalRunner.js +0 -102
  332. package/package/components/copilot/chat/__tests__/flow/initial/test5_initial.json +0 -53
  333. package/package/components/copilot/chat/__tests__/flow/initial/test6_initial.json +0 -68
  334. package/package/components/copilot/chat/__tests__/flow/initial/test7_initial.json +0 -120
  335. package/package/components/copilot/chat/__tests__/flow/variants/baseline.d.ts +0 -6
  336. package/package/components/copilot/chat/__tests__/flow/variants/baseline.js +0 -10
  337. package/package/components/copilot/chat/__tests__/flow/variants/index.d.ts +0 -3
  338. package/package/components/copilot/chat/__tests__/flow/variants/index.js +0 -3
  339. package/package/components/copilot/chat/__tests__/flow/variants/minimal-single-tool.d.ts +0 -15
  340. package/package/components/copilot/chat/__tests__/flow/variants/minimal-single-tool.js +0 -388
  341. package/package/components/copilot/chat/__tests__/shared/baseEvalRunner.d.ts +0 -45
  342. package/package/components/copilot/chat/__tests__/shared/baseEvalRunner.js +0 -121
  343. package/package/components/copilot/chat/__tests__/shared/baseLLMEvaluator.d.ts +0 -28
  344. package/package/components/copilot/chat/__tests__/shared/baseLLMEvaluator.js +0 -96
  345. package/package/components/copilot/chat/__tests__/shared/baseResultsWriter.d.ts +0 -32
  346. package/package/components/copilot/chat/__tests__/shared/baseResultsWriter.js +0 -130
  347. package/package/components/copilot/chat/__tests__/shared/baseVariants.d.ts +0 -45
  348. package/package/components/copilot/chat/__tests__/shared/baseVariants.js +0 -57
  349. package/package/components/copilot/chat/__tests__/shared/index.d.ts +0 -10
  350. package/package/components/copilot/chat/__tests__/shared/index.js +0 -5
  351. package/package/components/copilot/chat/__tests__/shared/types.d.ts +0 -105
  352. package/package/components/copilot/chat/__tests__/shared/types.js +0 -9
  353. package/package/components/copilot/chat/flow/utils.d.ts +0 -14
  354. package/package/components/copilot/chat/flow/utils.js +0 -108
  355. package/package/components/flows/agentToolUtils.test.js +0 -55
  356. /package/package/components/copilot/chat/{__tests__/app/appChat.eval.test.d.ts → app/core.test.d.ts} +0 -0
  357. /package/package/components/copilot/chat/{__tests__/flow/flowChat.eval.test.d.ts → flow/helperUtils.test.d.ts} +0 -0
  358. /package/package/components/{flows/agentToolUtils.test.d.ts → copilot/chat/flow/utils.test.d.ts} +0 -0
@@ -0,0 +1,531 @@
1
+ <script module lang="ts">import { diffTableEditorValues, makeAlterTableQueries } from './apps/components/display/dbtable/queries/alterTable';
2
+ import { renderForeignKey } from './apps/components/display/dbtable/queries/dbQueriesUtils';
3
+ export function apiSchemaToEditorSchema(apiSchema) {
4
+ const result = {};
5
+ for (const [schemaName, tables] of Object.entries(apiSchema)) {
6
+ result[schemaName] = {};
7
+ for (const [tableName, table] of Object.entries(tables)) {
8
+ if (!table || typeof table !== 'object')
9
+ continue;
10
+ result[schemaName][tableName] = {
11
+ name: table.name ?? tableName,
12
+ columns: (table.columns ?? []).map((c) => ({
13
+ name: c.name,
14
+ datatype: c.datatype,
15
+ primaryKey: c.primary_key ?? c.primaryKey,
16
+ defaultValue: c.default_value ?? c.defaultValue,
17
+ nullable: c.nullable
18
+ })),
19
+ foreignKeys: (table.foreign_keys ?? table.foreignKeys ?? []).map((fk) => ({
20
+ targetTable: fk.target_table ?? fk.targetTable,
21
+ columns: (fk.columns ?? []).map((col) => ({
22
+ sourceColumn: col.source_column ?? col.sourceColumn,
23
+ targetColumn: col.target_column ?? col.targetColumn
24
+ })),
25
+ onDelete: (fk.on_delete ?? fk.onDelete ?? 'NO ACTION'),
26
+ onUpdate: (fk.on_update ?? fk.onUpdate ?? 'NO ACTION'),
27
+ fk_constraint_name: fk.fk_constraint_name
28
+ })),
29
+ pk_constraint_name: table.pk_constraint_name
30
+ };
31
+ }
32
+ }
33
+ return result;
34
+ }
35
+ export function diffDatabaseSchemas(original, current) {
36
+ const diffs = [];
37
+ const allSchemas = new Set([...Object.keys(original), ...Object.keys(current)]);
38
+ for (const schemaName of allSchemas) {
39
+ const origTables = original[schemaName] ?? {};
40
+ const currTables = current[schemaName] ?? {};
41
+ const allTables = new Set([...Object.keys(origTables), ...Object.keys(currTables)]);
42
+ for (const tableName of allTables) {
43
+ const origTable = origTables[tableName];
44
+ const currTable = currTables[tableName];
45
+ if (!origTable && currTable) {
46
+ diffs.push({ schemaName, tableName, kind: 'added' });
47
+ }
48
+ else if (origTable && !currTable) {
49
+ diffs.push({ schemaName, tableName, kind: 'removed' });
50
+ }
51
+ else if (origTable && currTable) {
52
+ const currWithInitial = {
53
+ ...currTable,
54
+ columns: currTable.columns.map((col) => ({
55
+ ...col,
56
+ initialName: col.name,
57
+ defaultValue: col.defaultValue ? `{${col.defaultValue}}` : undefined
58
+ }))
59
+ };
60
+ const origTableTransformed = {
61
+ ...origTable,
62
+ columns: origTable.columns.map((col) => ({
63
+ ...col,
64
+ defaultValue: col.defaultValue ? `{${col.defaultValue}}` : undefined
65
+ }))
66
+ };
67
+ const diff = diffTableEditorValues(origTableTransformed, currWithInitial);
68
+ if (diff.operations.length > 0) {
69
+ diffs.push({ schemaName, tableName, kind: 'modified', operations: diff });
70
+ }
71
+ }
72
+ }
73
+ }
74
+ return diffs;
75
+ }
76
+ export function computeDatatableDiff(datatableName, originalSchema, parentSchema, forkSchema) {
77
+ return {
78
+ datatableName,
79
+ behindChanges: diffDatabaseSchemas(originalSchema, parentSchema),
80
+ aheadChanges: diffDatabaseSchemas(originalSchema, forkSchema),
81
+ originalSchema,
82
+ parentSchema,
83
+ forkSchema
84
+ };
85
+ }
86
+ /** Detect PostgreSQL auto-increment columns and return the serial type + cleaned props.
87
+ * e.g. bigint + nextval('seq'::regclass) → BIGSERIAL (no DEFAULT needed) */
88
+ function resolveColumnType(c) {
89
+ const dv = c.defaultValue ?? '';
90
+ if (/^{?nextval\(/.test(dv)) {
91
+ const dt = c.datatype?.toLowerCase() ?? '';
92
+ if (dt === 'bigint')
93
+ return { datatype: 'BIGSERIAL', defaultValue: undefined };
94
+ if (dt === 'integer' || dt === 'int')
95
+ return { datatype: 'SERIAL', defaultValue: undefined };
96
+ if (dt === 'smallint')
97
+ return { datatype: 'SMALLSERIAL', defaultValue: undefined };
98
+ }
99
+ return { datatype: c.datatype, defaultValue: c.defaultValue };
100
+ }
101
+ export function generateMigrationSql(change, sourceSchema) {
102
+ if (change.kind === 'modified' && change.operations) {
103
+ const queries = makeAlterTableQueries(change.operations, 'postgresql', change.schemaName);
104
+ if (queries.length === 0)
105
+ return '';
106
+ return 'BEGIN;\n' + queries.join('\n') + '\nCOMMIT;';
107
+ }
108
+ if (change.kind === 'added') {
109
+ const table = sourceSchema[change.schemaName]?.[change.tableName];
110
+ if (!table)
111
+ return '';
112
+ const colDefs = table.columns
113
+ .map((c) => {
114
+ const { datatype, defaultValue } = resolveColumnType(c);
115
+ let def = `"${c.name}" ${datatype}`;
116
+ if (c.nullable === false)
117
+ def += ' NOT NULL';
118
+ if (defaultValue)
119
+ def += ` DEFAULT ${defaultValue}`;
120
+ return def;
121
+ })
122
+ .join(',\n ');
123
+ const pkCols = table.columns.filter((c) => c.primaryKey).map((c) => `"${c.name}"`);
124
+ const pkLine = pkCols.length > 0 ? `,\n PRIMARY KEY (${pkCols.join(', ')})` : '';
125
+ const qualifiedName = `"${change.schemaName}"."${change.tableName}"`;
126
+ let sql = `BEGIN;\nCREATE TABLE ${qualifiedName} (\n ${colDefs}${pkLine}\n);`;
127
+ for (const fk of table.foreignKeys ?? []) {
128
+ const fkSql = renderForeignKey(fk, {
129
+ useSchema: true,
130
+ dbType: 'postgresql',
131
+ tableName: change.tableName
132
+ });
133
+ sql += `\nALTER TABLE ${qualifiedName} ADD ${fkSql};`;
134
+ }
135
+ sql += '\nCOMMIT;';
136
+ return sql;
137
+ }
138
+ if (change.kind === 'removed') {
139
+ return `BEGIN;\nDROP TABLE IF EXISTS "${change.schemaName}"."${change.tableName}";\nCOMMIT;`;
140
+ }
141
+ return '';
142
+ }
143
+ </script>
144
+
145
+ <script lang="ts">import { WorkspaceService } from '../gen';
146
+ import { Loader2, ChevronDown, ChevronRight, Plus, Minus, Pencil, Eye } from 'lucide-svelte';
147
+ import { Button } from './common';
148
+ import Drawer from './common/drawer/Drawer.svelte';
149
+ import SimpleEditor from './SimpleEditor.svelte';
150
+ import { sendUserToast } from '../toast';
151
+ import { runScriptAndPollResult } from './jobs/utils';
152
+ import YAML from 'yaml';
153
+ import DrawerContent from './common/drawer/DrawerContent.svelte';
154
+ import ConfirmationModal from './common/confirmationModal/ConfirmationModal.svelte';
155
+ import Alert from './common/alert/Alert.svelte';
156
+ import ResizeTransitionWrapper from './common/ResizeTransitionWrapper.svelte';
157
+ let { currentWorkspaceId, parentWorkspaceId } = $props();
158
+ let loading = $state(true);
159
+ let error = $state(undefined);
160
+ let diffs = $state([]);
161
+ let expandedDatatables = $state(new Set());
162
+ // Drawer state
163
+ let drawerOpen = $state(false);
164
+ let drawerChange = $state(undefined);
165
+ let drawerDiff = $state(undefined);
166
+ let drawerDirection = $state(undefined);
167
+ let migrationSql = $state('');
168
+ let migrationRunning = $state(false);
169
+ let confirmDeployOpen = $state(false);
170
+ async function loadDiffs() {
171
+ loading = true;
172
+ error = undefined;
173
+ diffs = [];
174
+ try {
175
+ const forkSettings = await WorkspaceService.getSettings({
176
+ workspace: currentWorkspaceId
177
+ });
178
+ const datatables = forkSettings.datatable?.datatables ?? {};
179
+ const forkedEntries = Object.entries(datatables).filter(([_, dt]) => dt.forked_from != null);
180
+ if (forkedEntries.length === 0) {
181
+ loading = false;
182
+ return;
183
+ }
184
+ const results = [];
185
+ for (const [dtName, dt] of forkedEntries) {
186
+ try {
187
+ const originalSchema = apiSchemaToEditorSchema(dt.forked_from?.schema ?? {});
188
+ const [parentSchemaRaw, forkSchemaRaw] = await Promise.all([
189
+ WorkspaceService.getDatatableFullSchema({
190
+ workspace: parentWorkspaceId,
191
+ requestBody: { source: `datatable://${dtName}` }
192
+ }),
193
+ WorkspaceService.getDatatableFullSchema({
194
+ workspace: currentWorkspaceId,
195
+ requestBody: { source: `datatable://${dtName}` }
196
+ })
197
+ ]);
198
+ const parentSchema = apiSchemaToEditorSchema(parentSchemaRaw);
199
+ const forkSchema = apiSchemaToEditorSchema(forkSchemaRaw);
200
+ const diff = computeDatatableDiff(dtName, originalSchema, parentSchema, forkSchema);
201
+ if (diff.aheadChanges.length > 0 || diff.behindChanges.length > 0) {
202
+ results.push(diff);
203
+ }
204
+ }
205
+ catch (e) {
206
+ console.error(`Failed to diff datatable ${dtName}:`, e);
207
+ }
208
+ }
209
+ diffs = results;
210
+ }
211
+ catch (e) {
212
+ error = e?.body ?? e?.message ?? String(e);
213
+ }
214
+ finally {
215
+ loading = false;
216
+ }
217
+ }
218
+ $effect(() => {
219
+ void [currentWorkspaceId, parentWorkspaceId];
220
+ loadDiffs();
221
+ });
222
+ function toggleExpanded(name) {
223
+ const next = new Set(expandedDatatables);
224
+ if (next.has(name))
225
+ next.delete(name);
226
+ else
227
+ next.add(name);
228
+ expandedDatatables = next;
229
+ }
230
+ function operationSummary(d) {
231
+ if (d.kind === 'added')
232
+ return 'New table';
233
+ if (d.kind === 'removed')
234
+ return 'Deleted table';
235
+ const ops = d.operations?.operations ?? [];
236
+ const parts = [];
237
+ const adds = ops.filter((o) => o.kind === 'addColumn').length;
238
+ const drops = ops.filter((o) => o.kind === 'dropColumn').length;
239
+ const alters = ops.filter((o) => o.kind === 'alterColumn').length;
240
+ const renames = ops.filter((o) => o.kind === 'renameTable').length;
241
+ const fkAdds = ops.filter((o) => o.kind === 'addForeignKey').length;
242
+ const fkDrops = ops.filter((o) => o.kind === 'dropForeignKey').length;
243
+ const pkChanges = ops.filter((o) => o.kind === 'addPrimaryKey' || o.kind === 'dropPrimaryKey').length;
244
+ if (adds)
245
+ parts.push(`+${adds} col`);
246
+ if (drops)
247
+ parts.push(`-${drops} col`);
248
+ if (alters)
249
+ parts.push(`~${alters} col`);
250
+ if (renames)
251
+ parts.push('renamed');
252
+ if (fkAdds)
253
+ parts.push(`+${fkAdds} FK`);
254
+ if (fkDrops)
255
+ parts.push(`-${fkDrops} FK`);
256
+ if (pkChanges)
257
+ parts.push('PK changed');
258
+ return parts.join(', ') || 'Modified';
259
+ }
260
+ function openReview(change, diff, direction) {
261
+ drawerChange = change;
262
+ drawerDiff = diff;
263
+ drawerDirection = direction;
264
+ // ahead = fork changed → migration runs on parent to deploy
265
+ // behind = parent changed → migration runs on fork to update
266
+ const sourceSchema = direction === 'ahead' ? diff.forkSchema : diff.parentSchema;
267
+ migrationSql =
268
+ '-- Migration is auto-generated on a best-effort basis. You can adjust it here \n\n' +
269
+ generateMigrationSql(change, sourceSchema);
270
+ drawerOpen = true;
271
+ }
272
+ function getDiffYaml() {
273
+ if (!drawerChange || !drawerDiff || !drawerDirection)
274
+ return { original: '', modified: '' };
275
+ const { schemaName, tableName } = drawerChange;
276
+ const origTable = drawerDiff.originalSchema[schemaName]?.[tableName];
277
+ // ahead = fork changed → show original vs fork
278
+ // behind = parent changed → show original vs parent
279
+ const changedSchema = drawerDirection === 'ahead' ? drawerDiff.forkSchema : drawerDiff.parentSchema;
280
+ const changedTable = changedSchema[schemaName]?.[tableName];
281
+ return {
282
+ original: origTable ? YAML.stringify(origTable) : '# table does not exist',
283
+ modified: changedTable ? YAML.stringify(changedTable) : '# table does not exist'
284
+ };
285
+ }
286
+ async function runMigration() {
287
+ if (!drawerDiff || !drawerChange || !drawerDirection)
288
+ return;
289
+ migrationRunning = true;
290
+ // ahead → run on parent; behind → run on fork
291
+ const targetWorkspace = drawerDirection === 'ahead' ? parentWorkspaceId : currentWorkspaceId;
292
+ const dtName = drawerDiff.datatableName;
293
+ try {
294
+ await runScriptAndPollResult({
295
+ workspace: targetWorkspace,
296
+ requestBody: {
297
+ args: { database: `datatable://${dtName}` },
298
+ language: 'postgresql',
299
+ content: migrationSql
300
+ }
301
+ });
302
+ }
303
+ catch (e) {
304
+ sendUserToast(e?.body ?? e?.message ?? String(e), true);
305
+ migrationRunning = false;
306
+ return;
307
+ }
308
+ // Update forked_from.schema for the migrated table
309
+ try {
310
+ const sourceSchema = drawerDirection === 'ahead' ? drawerDiff.forkSchema : drawerDiff.parentSchema;
311
+ const { schemaName, tableName } = drawerChange;
312
+ const newTableDef = sourceSchema[schemaName]?.[tableName];
313
+ const forkSettings = await WorkspaceService.getSettings({
314
+ workspace: currentWorkspaceId
315
+ });
316
+ const datatableConfig = forkSettings.datatable ?? { datatables: {} };
317
+ const dtConfig = datatableConfig.datatables[dtName];
318
+ if (dtConfig?.forked_from) {
319
+ const forkedFrom = dtConfig.forked_from;
320
+ if (!forkedFrom.schema)
321
+ forkedFrom.schema = {};
322
+ if (!forkedFrom.schema[schemaName])
323
+ forkedFrom.schema[schemaName] = {};
324
+ if (newTableDef) {
325
+ forkedFrom.schema[schemaName][tableName] = newTableDef;
326
+ }
327
+ else {
328
+ delete forkedFrom.schema[schemaName][tableName];
329
+ }
330
+ await WorkspaceService.editDataTableConfig({
331
+ workspace: currentWorkspaceId,
332
+ requestBody: { settings: datatableConfig }
333
+ });
334
+ }
335
+ }
336
+ catch (e) {
337
+ console.error('Failed to update forked_from schema:', e);
338
+ }
339
+ migrationRunning = false;
340
+ drawerOpen = false;
341
+ sendUserToast('Migration applied successfully');
342
+ await loadDiffs();
343
+ }
344
+ </script>
345
+
346
+ <h3 class="text-sm font-semibold">Datatable schema changes</h3>
347
+ {#if loading}
348
+ <div class="flex items-center gap-2 text-xs text-tertiary py-2">
349
+ <Loader2 class="w-4 h-4 animate-spin" /> Loading datatable diffs...
350
+ </div>
351
+ {:else if error}
352
+ <div class="text-xs text-red-500 py-2">Failed to load datatable diffs: {error}</div>
353
+ {:else if diffs.length > 0}
354
+ <div class="flex flex-col gap-2 mt-3 mb-1">
355
+ {#each diffs as diff}
356
+ <ResizeTransitionWrapper class="border rounded-md" innerClass="w-full" vertical>
357
+ <button
358
+ class="w-full flex items-center justify-between px-3 py-2 hover:bg-surface-hover"
359
+ onclick={() => toggleExpanded(diff.datatableName)}
360
+ >
361
+ <span class="text-xs font-medium">{diff.datatableName}</span>
362
+ <div class="flex items-center gap-2 text-2xs text-tertiary">
363
+ {#if diff.aheadChanges.length > 0}
364
+ <span class="text-blue-500">{diff.aheadChanges.length} ahead</span>
365
+ {/if}
366
+ {#if diff.behindChanges.length > 0}
367
+ <span class="text-orange-500">{diff.behindChanges.length} behind</span>
368
+ {/if}
369
+ {#if expandedDatatables.has(diff.datatableName)}
370
+ <ChevronDown class="w-3 h-3" />
371
+ {:else}
372
+ <ChevronRight class="w-3 h-3" />
373
+ {/if}
374
+ </div>
375
+ </button>
376
+
377
+ {#if expandedDatatables.has(diff.datatableName)}
378
+ <div class="border-t divide-y">
379
+ {#if diff.aheadChanges.length > 0}
380
+ <div class="px-3 py-1.5">
381
+ <div class="text-2xs font-semibold text-blue-500 mb-1">Fork changes (ahead)</div>
382
+ {#each diff.aheadChanges as change}
383
+ <div class="flex items-center gap-2 text-xs py-0.5">
384
+ {#if change.kind === 'added'}
385
+ <Plus class="w-3 h-3 text-green-500 shrink-0" />
386
+ {:else if change.kind === 'removed'}
387
+ <Minus class="w-3 h-3 text-red-500 shrink-0" />
388
+ {:else}
389
+ <Pencil class="w-3 h-3 text-yellow-500 shrink-0" />
390
+ {/if}
391
+ <span class="text-tertiary">{change.schemaName}.</span>
392
+ <span class="font-medium">{change.tableName}</span>
393
+ <span class="text-tertiary text-2xs grow">{operationSummary(change)}</span>
394
+ <Button
395
+ size="xs"
396
+ variant="subtle"
397
+ startIcon={{ icon: Eye }}
398
+ onclick={() => openReview(change, diff, 'ahead')}
399
+ >
400
+ Review
401
+ </Button>
402
+ </div>
403
+ {/each}
404
+ </div>
405
+ {/if}
406
+ {#if diff.behindChanges.length > 0}
407
+ <div class="px-3 py-1.5">
408
+ <div class="text-2xs font-semibold text-orange-500 mb-1">
409
+ Parent changes (behind)
410
+ </div>
411
+ {#each diff.behindChanges as change}
412
+ <div class="flex items-center gap-2 text-xs py-0.5">
413
+ {#if change.kind === 'added'}
414
+ <Plus class="w-3 h-3 text-green-500 shrink-0" />
415
+ {:else if change.kind === 'removed'}
416
+ <Minus class="w-3 h-3 text-red-500 shrink-0" />
417
+ {:else}
418
+ <Pencil class="w-3 h-3 text-yellow-500 shrink-0" />
419
+ {/if}
420
+ <span class="text-tertiary">{change.schemaName}.</span>
421
+ <span class="font-medium">{change.tableName}</span>
422
+ <span class="text-tertiary text-2xs grow">{operationSummary(change)}</span>
423
+ <Button
424
+ size="xs"
425
+ variant="subtle"
426
+ startIcon={{ icon: Eye }}
427
+ onclick={() => openReview(change, diff, 'behind')}
428
+ >
429
+ Review
430
+ </Button>
431
+ </div>
432
+ {/each}
433
+ </div>
434
+ {/if}
435
+ </div>
436
+ {/if}
437
+ </ResizeTransitionWrapper>
438
+ {/each}
439
+ </div>
440
+ {:else}
441
+ <span class="text-xs text-secondary"> No changes detected </span>
442
+ {/if}
443
+
444
+ <Drawer bind:open={drawerOpen} size="900px">
445
+ {#if drawerChange && drawerDiff && drawerDirection}
446
+ {@const yaml = getDiffYaml()}
447
+ <DrawerContent
448
+ on:close={() => (drawerOpen = false)}
449
+ title="{drawerChange.schemaName}.{drawerChange.tableName} ({drawerDirection === 'ahead'
450
+ ? 'Fork → Parent'
451
+ : 'Parent → Fork'})"
452
+ >
453
+ {#snippet actions()}
454
+ <Button
455
+ variant="accent"
456
+ loading={migrationRunning}
457
+ onclick={() => {
458
+ if (drawerDirection === 'ahead') {
459
+ confirmDeployOpen = true
460
+ } else {
461
+ runMigration()
462
+ }
463
+ }}
464
+ >
465
+ Run migration
466
+ </Button>
467
+ {/snippet}
468
+ <div class="flex flex-col h-full">
469
+ <Alert title="Changes to {drawerChange.tableName}" type="info">
470
+ {#if drawerDirection == 'ahead'}
471
+ You have made these changes in {currentWorkspaceId} that are not yet deployed in {parentWorkspaceId}.
472
+ {:else if drawerDirection == 'behind'}
473
+ These changes were made in {parentWorkspaceId} but the current workspace is not up to date.
474
+ {/if}
475
+ </Alert>
476
+ <!-- Diff section -->
477
+ <div style="height: 45%;">
478
+ <div class="py-1.5 text-2xs font-semibold text-secondary">
479
+ Schema diff (parent ↔ fork)
480
+ </div>
481
+ <div class="h-[calc(100%-28px)] border rounded-md overflow-clip">
482
+ {#await import('./DiffEditor.svelte')}
483
+ <div class="flex items-center justify-center h-full">
484
+ <Loader2 class="w-5 h-5 animate-spin" />
485
+ </div>
486
+ {:then Module}
487
+ <Module.default
488
+ open={true}
489
+ automaticLayout
490
+ className="h-full"
491
+ defaultLang="yaml"
492
+ defaultOriginal={yaml.original}
493
+ defaultModified={yaml.modified}
494
+ readOnly
495
+ />
496
+ {/await}
497
+ </div>
498
+ </div>
499
+
500
+ <!-- SQL migration section -->
501
+ <div class="flex flex-col grow overflow-hidden mt-4">
502
+ <div class="py-1.5 text-2xs font-semibold text-secondary"> SQL migration </div>
503
+ <div class="grow overflow-clip rounded-md border">
504
+ <SimpleEditor class="h-full" lang="sql" bind:code={migrationSql} />
505
+ </div>
506
+ </div>
507
+ </div>
508
+ </DrawerContent>
509
+ {/if}
510
+ </Drawer>
511
+
512
+ <ConfirmationModal
513
+ open={confirmDeployOpen}
514
+ title="Deploy to parent workspace"
515
+ confirmationText="Run migration"
516
+ onConfirmed={async () => {
517
+ confirmDeployOpen = false
518
+ await runMigration()
519
+ }}
520
+ onCanceled={() => {
521
+ confirmDeployOpen = false
522
+ }}
523
+ >
524
+ <p class="text-sm">
525
+ This will run the following SQL on workspace <b>{parentWorkspaceId}</b>:
526
+ </p>
527
+ <pre
528
+ class="mt-2 p-3 bg-surface-secondary rounded text-xs font-mono whitespace-pre-wrap max-h-60 overflow-auto"
529
+ >{migrationSql}</pre
530
+ >
531
+ </ConfirmationModal>
@@ -0,0 +1,29 @@
1
+ import type { TableEditorValues } from './apps/components/display/dbtable/tableEditor';
2
+ import { type AlterTableValues } from './apps/components/display/dbtable/queries/alterTable';
3
+ import type { GetDatatableFullSchemaResponse } from '../gen';
4
+ export type DatabaseSchema = Record<string, Record<string, TableEditorValues>>;
5
+ export declare function apiSchemaToEditorSchema(apiSchema: GetDatatableFullSchemaResponse): DatabaseSchema;
6
+ export type TableDiff = {
7
+ schemaName: string;
8
+ tableName: string;
9
+ kind: 'added' | 'removed' | 'modified';
10
+ operations?: AlterTableValues;
11
+ };
12
+ export type DatatableDiff = {
13
+ datatableName: string;
14
+ aheadChanges: TableDiff[];
15
+ behindChanges: TableDiff[];
16
+ originalSchema: DatabaseSchema;
17
+ parentSchema: DatabaseSchema;
18
+ forkSchema: DatabaseSchema;
19
+ };
20
+ export declare function diffDatabaseSchemas(original: DatabaseSchema, current: DatabaseSchema): TableDiff[];
21
+ export declare function computeDatatableDiff(datatableName: string, originalSchema: DatabaseSchema, parentSchema: DatabaseSchema, forkSchema: DatabaseSchema): DatatableDiff;
22
+ export declare function generateMigrationSql(change: TableDiff, sourceSchema: DatabaseSchema): string;
23
+ interface Props {
24
+ currentWorkspaceId: string;
25
+ parentWorkspaceId: string;
26
+ }
27
+ declare const DatatableSchemaDiff: import("svelte").Component<Props, {}, "">;
28
+ type DatatableSchemaDiff = ReturnType<typeof DatatableSchemaDiff>;
29
+ export default DatatableSchemaDiff;
@@ -224,12 +224,14 @@ $effect(() => {
224
224
  loadSelectedTagsInfo(selectedTags);
225
225
  });
226
226
  $effect(() => {
227
- loadWorkspaces();
227
+ if (!disabled) {
228
+ loadWorkspaces();
229
+ }
228
230
  });
229
231
  async function loadWorkspaces() {
230
232
  try {
231
233
  workspacesLoading = true;
232
- const ws = await WorkspaceService.listWorkspaces();
234
+ const ws = await WorkspaceService.listWorkspacesAsSuperAdmin();
233
235
  workspaces = ws.map((w) => ({ id: w.id, name: w.name }));
234
236
  }
235
237
  catch (e) {
@@ -3,25 +3,30 @@ import { ExternalLink, Loader2, Save } from 'lucide-svelte';
3
3
  import { SettingService, WorkerService, WorkspaceService } from '../gen';
4
4
  import { sendUserToast } from '../toast';
5
5
  import { enterpriseLicense, superadmin } from '../stores';
6
- import { DEFAULT_TAGS_PER_WORKSPACE_SETTING, DEFAULT_TAGS_WORKSPACES_SETTING, PREVIEW_TAGS_OVERRIDE_SETTING } from '../consts';
6
+ import { DEFAULT_TAGS_PER_WORKSPACE_SETTING, DEFAULT_TAGS_WORKSPACES_SETTING, FORK_WORKSPACE_TAG_APPEND_FORK_SUFFIX_SETTING, PREVIEW_TAGS_OVERRIDE_SETTING } from '../consts';
7
7
  import Toggle from './Toggle.svelte';
8
8
  import MultiSelect from './select/MultiSelect.svelte';
9
9
  import { safeSelectItems } from './select/utils.svelte';
10
10
  import Badge from './common/badge/Badge.svelte';
11
11
  import Section from './Section.svelte';
12
+ import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte';
13
+ import ToggleButton from './common/toggleButton-v2/ToggleButton.svelte';
12
14
  let { defaultTagPerWorkspace = $bindable(undefined), defaultTagWorkspaces = $bindable([]) } = $props();
13
15
  let defaultTags = $state(undefined);
14
16
  let limitToWorkspaces = $state(false);
15
17
  let previewTagsOverride = $state(false);
18
+ let forkAppendForkSuffix = $state(false);
16
19
  // Change detection
17
20
  let originalDefaultTagPerWorkspace = $state(defaultTagPerWorkspace);
18
21
  let originalDefaultTagWorkspaces = $state(defaultTagWorkspaces);
19
22
  let originalPreviewTagsOverride = $state(false);
23
+ let originalForkAppendForkSuffix = $state(false);
20
24
  // Detect changes
21
25
  let hasChanges = $derived(originalDefaultTagPerWorkspace !== defaultTagPerWorkspace ||
22
26
  JSON.stringify($state.snapshot(originalDefaultTagWorkspaces)?.sort() || []) !==
23
27
  JSON.stringify($state.snapshot(defaultTagWorkspaces)?.sort() || []) ||
24
- originalPreviewTagsOverride !== previewTagsOverride);
28
+ originalPreviewTagsOverride !== previewTagsOverride ||
29
+ originalForkAppendForkSuffix !== forkAppendForkSuffix);
25
30
  let workspaces = $state([]);
26
31
  async function loadWorkspaces() {
27
32
  workspaces = (await WorkspaceService.listWorkspacesAsSuperAdmin()).map((m) => m.id);
@@ -39,6 +44,11 @@ async function loadDefaultTags() {
39
44
  key: PREVIEW_TAGS_OVERRIDE_SETTING
40
45
  })) ?? false;
41
46
  originalPreviewTagsOverride = previewTagsOverride;
47
+ const forkSetting = (await SettingService.getGlobal({
48
+ key: FORK_WORKSPACE_TAG_APPEND_FORK_SUFFIX_SETTING
49
+ }));
50
+ forkAppendForkSuffix = forkSetting ?? false;
51
+ originalForkAppendForkSuffix = forkAppendForkSuffix;
42
52
  }
43
53
  catch (err) {
44
54
  sendUserToast(`Could not load default tags: ${err}`, true);
@@ -65,10 +75,17 @@ async function handleSave() {
65
75
  value: previewTagsOverride
66
76
  }
67
77
  });
78
+ await SettingService.setGlobal({
79
+ key: FORK_WORKSPACE_TAG_APPEND_FORK_SUFFIX_SETTING,
80
+ requestBody: {
81
+ value: forkAppendForkSuffix
82
+ }
83
+ });
68
84
  // Update original state after save
69
85
  originalDefaultTagPerWorkspace = defaultTagPerWorkspace;
70
86
  originalDefaultTagWorkspaces = [...(defaultTagWorkspaces || [])];
71
87
  originalPreviewTagsOverride = previewTagsOverride;
88
+ originalForkAppendForkSuffix = forkAppendForkSuffix;
72
89
  loadDefaultTags();
73
90
  sendUserToast('Saved');
74
91
  }
@@ -126,6 +143,29 @@ loadWorkspaces();
126
143
  />
127
144
  </div>
128
145
  {#if defaultTagPerWorkspace}
146
+ <div class="flex flex-col gap-1">
147
+ <span class="text-xs font-semibold">Fork workspace behavior</span>
148
+ <ToggleButtonGroup
149
+ selected={forkAppendForkSuffix ? 'parent-fork' : 'parent'}
150
+ onSelected={(v) => (forkAppendForkSuffix = v === 'parent-fork')}
151
+ disabled={!$enterpriseLicense}
152
+ >
153
+ {#snippet children({ item })}
154
+ <ToggleButton
155
+ value="parent"
156
+ label="Use parent workspace tag"
157
+ tooltip={'Fork jobs are tagged with the parent workspace id (e.g. python3-{parent_id}), so they are picked up by workers assigned to the parent workspace.'}
158
+ {item}
159
+ />
160
+ <ToggleButton
161
+ value="parent-fork"
162
+ label="Use parent workspace tag + -fork suffix"
163
+ tooltip={'Fork jobs are tagged with the parent workspace id and a "-fork" suffix (e.g. python3-{parent_id}-fork), so all forks of a given parent share a dedicated tag. Route these jobs to workers provisioned specifically for forks of the parent.'}
164
+ {item}
165
+ />
166
+ {/snippet}
167
+ </ToggleButtonGroup>
168
+ </div>
129
169
  <Toggle
130
170
  bind:checked={limitToWorkspaces}
131
171
  options={{ right: 'only for some workspaces' }}
@@ -17,7 +17,7 @@ export async function openDrawer(initialPath_l, kind_l, additionalInformation_l)
17
17
  }
18
18
  </script>
19
19
 
20
- <Drawer bind:this={drawer} size="900px">
20
+ <Drawer bind:this={drawer} size="1200px">
21
21
  <DrawerContent title="Deploy {initialPath}" on:close={drawer.closeDrawer}>
22
22
  {#if (kind != 'trigger' && kind != undefined && initialPath != undefined) || (kind === 'trigger' && initialPath != undefined && additionalInformation?.triggers != undefined)}
23
23
  <DeployWorkspace