@promptbook/cli 0.104.0-1 → 0.104.0-11

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 (229) hide show
  1. package/apps/agents-server/config.ts +1 -3
  2. package/apps/agents-server/next.config.ts +2 -2
  3. package/apps/agents-server/package.json +7 -3
  4. package/apps/agents-server/public/fonts/OpenMoji-color-cbdt.woff2 +0 -0
  5. package/apps/agents-server/public/swagger.json +115 -0
  6. package/apps/agents-server/scripts/generate-reserved-paths/generate-reserved-paths.ts +54 -0
  7. package/apps/agents-server/scripts/generate-reserved-paths/tsconfig.json +19 -0
  8. package/apps/agents-server/src/app/AddAgentButton.tsx +47 -21
  9. package/apps/agents-server/src/app/actions.ts +22 -5
  10. package/apps/agents-server/src/app/admin/browser-test/BrowserTestClient.tsx +211 -0
  11. package/apps/agents-server/src/app/admin/browser-test/page.tsx +13 -0
  12. package/apps/agents-server/src/app/admin/chat-feedback/ChatFeedbackClient.tsx +221 -274
  13. package/apps/agents-server/src/app/admin/chat-history/ChatHistoryClient.tsx +94 -137
  14. package/apps/agents-server/src/app/admin/files/FilesGalleryClient.tsx +263 -0
  15. package/apps/agents-server/src/app/admin/files/actions.ts +61 -0
  16. package/apps/agents-server/src/app/admin/files/page.tsx +13 -0
  17. package/apps/agents-server/src/app/admin/image-generator-test/ImageGeneratorTestClient.tsx +169 -0
  18. package/apps/agents-server/src/app/admin/image-generator-test/page.tsx +13 -0
  19. package/apps/agents-server/src/app/admin/images/ImagesGalleryClient.tsx +256 -0
  20. package/apps/agents-server/src/app/admin/images/actions.ts +60 -0
  21. package/apps/agents-server/src/app/admin/images/page.tsx +13 -0
  22. package/apps/agents-server/src/app/admin/messages/MessagesClient.tsx +294 -0
  23. package/apps/agents-server/src/app/admin/messages/page.tsx +13 -0
  24. package/apps/agents-server/src/app/admin/messages/send-email/SendEmailClient.tsx +104 -0
  25. package/apps/agents-server/src/app/admin/messages/send-email/actions.ts +35 -0
  26. package/apps/agents-server/src/app/admin/messages/send-email/page.tsx +13 -0
  27. package/apps/agents-server/src/app/admin/metadata/MetadataClient.tsx +23 -19
  28. package/apps/agents-server/src/app/admin/search-engine-test/SearchEngineTestClient.tsx +109 -0
  29. package/apps/agents-server/src/app/admin/search-engine-test/actions.ts +17 -0
  30. package/apps/agents-server/src/app/admin/search-engine-test/page.tsx +13 -0
  31. package/apps/agents-server/src/app/agents/[agentName]/AgentChatWrapper.tsx +15 -1
  32. package/apps/agents-server/src/app/agents/[agentName]/AgentOptionsMenu.tsx +51 -9
  33. package/apps/agents-server/src/app/agents/[agentName]/AgentProfileChat.tsx +47 -4
  34. package/apps/agents-server/src/app/agents/[agentName]/AgentProfileWrapper.tsx +53 -11
  35. package/apps/agents-server/src/app/agents/[agentName]/_utils.ts +23 -3
  36. package/apps/agents-server/src/app/agents/[agentName]/agentLinks.tsx +8 -8
  37. package/apps/agents-server/src/app/agents/[agentName]/api/agents/route.ts +17 -26
  38. package/apps/agents-server/src/app/agents/[agentName]/api/book/route.ts +4 -2
  39. package/apps/agents-server/src/app/agents/[agentName]/api/chat/route.ts +20 -0
  40. package/apps/agents-server/src/app/agents/[agentName]/api/mcp/route.ts +6 -11
  41. package/apps/agents-server/src/app/agents/[agentName]/api/profile/route.ts +5 -1
  42. package/apps/agents-server/src/app/agents/[agentName]/api/voice/route.ts +5 -2
  43. package/apps/agents-server/src/app/agents/[agentName]/book/BookEditorWrapper.tsx +20 -16
  44. package/apps/agents-server/src/app/agents/[agentName]/book/page.tsx +15 -2
  45. package/apps/agents-server/src/app/agents/[agentName]/book+chat/page.tsx +15 -2
  46. package/apps/agents-server/src/app/agents/[agentName]/chat/page.tsx +12 -0
  47. package/apps/agents-server/src/app/agents/[agentName]/code/api/route.ts +68 -0
  48. package/apps/agents-server/src/app/agents/[agentName]/code/page.tsx +223 -0
  49. package/apps/agents-server/src/app/agents/[agentName]/generateAgentMetadata.ts +5 -0
  50. package/apps/agents-server/src/app/agents/[agentName]/history/actions.ts +2 -2
  51. package/apps/agents-server/src/app/agents/[agentName]/history/page.tsx +10 -3
  52. package/apps/agents-server/src/app/agents/[agentName]/images/default-avatar.png/getAgentDefaultAvatarPrompt.ts +31 -0
  53. package/apps/agents-server/src/app/agents/[agentName]/images/default-avatar.png/route.ts +194 -0
  54. package/apps/agents-server/src/app/agents/[agentName]/images/icon-256.png/route.tsx +14 -2
  55. package/apps/agents-server/src/app/agents/[agentName]/images/page.tsx +200 -0
  56. package/apps/agents-server/src/app/agents/[agentName]/images/screenshot-fullhd.png/route.tsx +4 -3
  57. package/apps/agents-server/src/app/agents/[agentName]/images/screenshot-phone.png/route.tsx +4 -3
  58. package/apps/agents-server/src/app/agents/[agentName]/integration/page.tsx +10 -3
  59. package/apps/agents-server/src/app/agents/[agentName]/links/page.tsx +11 -4
  60. package/apps/agents-server/src/app/agents/[agentName]/opengraph-image.tsx +11 -2
  61. package/apps/agents-server/src/app/agents/[agentName]/page.tsx +18 -10
  62. package/apps/agents-server/src/app/agents/[agentName]/system-message/page.tsx +100 -0
  63. package/apps/agents-server/src/app/api/admin-email/route.ts +12 -0
  64. package/apps/agents-server/src/app/api/agents/[agentName]/clone/route.ts +13 -14
  65. package/apps/agents-server/src/app/api/agents/[agentName]/restore/route.ts +20 -0
  66. package/apps/agents-server/src/app/api/agents/[agentName]/route.ts +43 -1
  67. package/apps/agents-server/src/app/api/agents/route.ts +28 -3
  68. package/apps/agents-server/src/app/api/api-tokens/route.ts +6 -7
  69. package/apps/agents-server/src/app/api/browser-test/act/route.ts +141 -0
  70. package/apps/agents-server/src/app/api/browser-test/screenshot/route.ts +30 -0
  71. package/apps/agents-server/src/app/api/browser-test/scroll-facebook/route.ts +62 -0
  72. package/apps/agents-server/src/app/api/docs/book.md/route.ts +61 -0
  73. package/apps/agents-server/src/app/api/emails/incoming/sendgrid/route.ts +48 -0
  74. package/apps/agents-server/src/app/api/federated-agents/route.ts +12 -0
  75. package/apps/agents-server/src/app/api/images/[filename]/route.ts +128 -0
  76. package/apps/agents-server/src/app/api/messages/route.ts +102 -0
  77. package/apps/agents-server/src/app/api/metadata/route.ts +5 -6
  78. package/apps/agents-server/src/app/api/upload/route.ts +128 -45
  79. package/apps/agents-server/src/app/docs/[docId]/page.tsx +2 -3
  80. package/apps/agents-server/src/app/docs/page.tsx +12 -12
  81. package/apps/agents-server/src/app/globals.css +140 -33
  82. package/apps/agents-server/src/app/humans.txt/route.ts +1 -1
  83. package/apps/agents-server/src/app/layout.tsx +27 -22
  84. package/apps/agents-server/src/app/page.tsx +54 -6
  85. package/apps/agents-server/src/app/recycle-bin/actions.ts +20 -14
  86. package/apps/agents-server/src/app/recycle-bin/page.tsx +27 -41
  87. package/apps/agents-server/src/app/robots.txt/route.ts +1 -1
  88. package/apps/agents-server/src/app/security.txt/route.ts +1 -1
  89. package/apps/agents-server/src/app/sitemap.xml/route.ts +9 -7
  90. package/apps/agents-server/src/app/swagger/page.tsx +14 -0
  91. package/apps/agents-server/src/components/AgentProfile/AgentCapabilityChips.tsx +38 -0
  92. package/apps/agents-server/src/components/AgentProfile/AgentProfile.tsx +44 -116
  93. package/apps/agents-server/src/components/AgentProfile/AgentProfileImage.tsx +92 -0
  94. package/apps/agents-server/src/components/AgentProfile/QrCodeModal.tsx +0 -1
  95. package/apps/agents-server/src/components/AgentProfile/useAgentBackground.ts +97 -0
  96. package/apps/agents-server/src/components/Auth/AuthControls.tsx +5 -4
  97. package/apps/agents-server/src/components/DeletedAgentBanner.tsx +26 -0
  98. package/apps/agents-server/src/components/DocsToolbar/DocsToolbar.tsx +38 -0
  99. package/apps/agents-server/src/components/DocumentationContent/DocumentationContent.tsx +11 -9
  100. package/apps/agents-server/src/components/Footer/Footer.tsx +5 -5
  101. package/apps/agents-server/src/components/ForgottenPasswordDialog/ForgottenPasswordDialog.tsx +61 -0
  102. package/apps/agents-server/src/components/Header/Header.tsx +130 -40
  103. package/apps/agents-server/src/components/Homepage/AgentCard.tsx +150 -23
  104. package/apps/agents-server/src/components/Homepage/AgentsList.tsx +93 -15
  105. package/apps/agents-server/src/components/Homepage/DeletedAgentsList.tsx +66 -0
  106. package/apps/agents-server/src/components/Homepage/ExternalAgentsSection.tsx +12 -3
  107. package/apps/agents-server/src/components/Homepage/ExternalAgentsSectionClient.tsx +19 -10
  108. package/apps/agents-server/src/components/LayoutWrapper/LayoutWrapper.tsx +3 -2
  109. package/apps/agents-server/src/components/LoginForm/LoginForm.tsx +50 -1
  110. package/apps/agents-server/src/components/NewAgentDialog/NewAgentDialog.tsx +88 -0
  111. package/apps/agents-server/src/components/NotFoundPage/NotFoundPage.tsx +7 -2
  112. package/apps/agents-server/src/components/OpenMojiIcon/OpenMojiIcon.tsx +16 -7
  113. package/apps/agents-server/src/components/PrintHeader/PrintHeader.tsx +4 -4
  114. package/apps/agents-server/src/components/RegisterUserDialog/RegisterUserDialog.tsx +61 -0
  115. package/apps/agents-server/src/components/VercelDeploymentCard/VercelDeploymentCard.tsx +2 -0
  116. package/apps/agents-server/src/components/_utils/generateMetaTxt.ts +12 -10
  117. package/apps/agents-server/src/components/_utils/headlessParam.tsx +7 -3
  118. package/apps/agents-server/src/database/$getTableName.ts +1 -0
  119. package/apps/agents-server/src/database/$provideSupabaseForBrowser.ts +3 -3
  120. package/apps/agents-server/src/database/$provideSupabaseForServer.ts +1 -1
  121. package/apps/agents-server/src/database/$provideSupabaseForWorker.ts +3 -3
  122. package/apps/agents-server/src/database/metadataDefaults.ts +19 -1
  123. package/apps/agents-server/src/database/migrate.ts +34 -1
  124. package/apps/agents-server/src/database/migrations/2025-11-0001-initial-schema.sql +1 -3
  125. package/apps/agents-server/src/database/migrations/2025-11-0002-metadata-table.sql +1 -3
  126. package/apps/agents-server/src/database/migrations/2025-12-0240-agent-public-id.sql +3 -0
  127. package/apps/agents-server/src/database/migrations/2025-12-0360-agent-deleted-at.sql +1 -0
  128. package/apps/agents-server/src/database/migrations/2025-12-0370-image-table.sql +19 -0
  129. package/apps/agents-server/src/database/migrations/2025-12-0380-agent-visibility.sql +1 -0
  130. package/apps/agents-server/src/database/migrations/2025-12-0390-upload-tracking.sql +20 -0
  131. package/apps/agents-server/src/database/migrations/2025-12-0401-file-upload-status.sql +13 -0
  132. package/apps/agents-server/src/database/migrations/2025-12-0402-message-table.sql +42 -0
  133. package/apps/agents-server/src/database/migrations/2025-12-0403-generation-lock-table.sql +15 -0
  134. package/apps/agents-server/src/database/migrations/2025-12-0640-openai-assistant-cache.sql +12 -0
  135. package/apps/agents-server/src/database/migrations/2025-12-0820-agent-history-permanent-id.sql +29 -0
  136. package/apps/agents-server/src/database/migrations/2025-12-0830-image-purpose.sql +5 -0
  137. package/apps/agents-server/src/database/migrations/2025-12-0890-file-agent-id.sql +5 -0
  138. package/apps/agents-server/src/database/schema.ts +244 -4
  139. package/apps/agents-server/src/generated/reservedPaths.ts +32 -0
  140. package/apps/agents-server/src/message-providers/email/_common/Email.ts +73 -0
  141. package/apps/agents-server/src/message-providers/email/_common/utils/TODO.txt +1 -0
  142. package/apps/agents-server/src/message-providers/email/_common/utils/parseEmailAddress.test.ts.todo +108 -0
  143. package/apps/agents-server/src/message-providers/email/_common/utils/parseEmailAddress.ts +62 -0
  144. package/apps/agents-server/src/message-providers/email/_common/utils/parseEmailAddresses.test.ts.todo +117 -0
  145. package/apps/agents-server/src/message-providers/email/_common/utils/parseEmailAddresses.ts +19 -0
  146. package/apps/agents-server/src/message-providers/email/_common/utils/stringifyEmailAddress.test.ts.todo +119 -0
  147. package/apps/agents-server/src/message-providers/email/_common/utils/stringifyEmailAddress.ts +19 -0
  148. package/apps/agents-server/src/message-providers/email/_common/utils/stringifyEmailAddresses.test.ts.todo +74 -0
  149. package/apps/agents-server/src/message-providers/email/_common/utils/stringifyEmailAddresses.ts +14 -0
  150. package/apps/agents-server/src/message-providers/email/sendgrid/SendgridMessageProvider.ts +44 -0
  151. package/apps/agents-server/src/message-providers/email/sendgrid/parseInboundSendgridEmail.ts +49 -0
  152. package/apps/agents-server/src/message-providers/email/zeptomail/ZeptomailMessageProvider.ts +51 -0
  153. package/apps/agents-server/src/message-providers/index.ts +13 -0
  154. package/apps/agents-server/src/message-providers/interfaces/MessageProvider.ts +11 -0
  155. package/apps/agents-server/src/middleware.ts +19 -23
  156. package/apps/agents-server/src/tools/$provideBrowserForServer.ts +32 -0
  157. package/apps/agents-server/src/tools/$provideCdnForServer.ts +7 -2
  158. package/apps/agents-server/src/utils/auth.ts +117 -17
  159. package/apps/agents-server/src/utils/cdn/classes/TrackedFilesStorage.ts +57 -0
  160. package/apps/agents-server/src/utils/cdn/classes/VercelBlobStorage.ts +4 -0
  161. package/apps/agents-server/src/utils/cdn/interfaces/IFilesStorage.ts +18 -0
  162. package/apps/agents-server/src/utils/content/extractBodyContentFromHtml.ts +19 -0
  163. package/apps/agents-server/src/utils/getUserIdFromRequest.ts +35 -0
  164. package/apps/agents-server/src/utils/handleChatCompletion.ts +65 -5
  165. package/apps/agents-server/src/utils/messages/sendMessage.ts +91 -0
  166. package/apps/agents-server/src/utils/messagesAdmin.ts +72 -0
  167. package/apps/agents-server/src/utils/normalization/filenameToPrompt.test.ts +36 -0
  168. package/apps/agents-server/src/utils/normalization/filenameToPrompt.ts +25 -0
  169. package/apps/agents-server/src/utils/validateApiKey.ts +7 -11
  170. package/esm/index.es.js +1534 -1330
  171. package/esm/index.es.js.map +1 -1
  172. package/esm/typings/servers.d.ts +8 -0
  173. package/esm/typings/src/_packages/core.index.d.ts +2 -0
  174. package/esm/typings/src/_packages/types.index.d.ts +16 -2
  175. package/esm/typings/src/book-2.0/agent-source/AgentBasicInformation.d.ts +29 -1
  176. package/esm/typings/src/book-2.0/agent-source/createAgentModelRequirements.d.ts +6 -6
  177. package/esm/typings/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments.closed.test.d.ts +1 -0
  178. package/esm/typings/src/book-2.0/utils/generatePlaceholderAgentProfileImageUrl.d.ts +3 -3
  179. package/esm/typings/src/book-components/Chat/Chat/ChatMessageItem.d.ts +5 -1
  180. package/esm/typings/src/book-components/Chat/Chat/ChatProps.d.ts +5 -0
  181. package/esm/typings/src/book-components/Chat/CodeBlock/CodeBlock.d.ts +13 -0
  182. package/esm/typings/src/book-components/Chat/MarkdownContent/MarkdownContent.d.ts +1 -0
  183. package/esm/typings/src/book-components/Chat/types/ChatMessage.d.ts +9 -13
  184. package/esm/typings/src/book-components/_common/Dropdown/Dropdown.d.ts +3 -3
  185. package/esm/typings/src/book-components/_common/HamburgerMenu/HamburgerMenu.d.ts +1 -1
  186. package/esm/typings/src/book-components/_common/MenuHoisting/MenuHoistingContext.d.ts +56 -0
  187. package/esm/typings/src/book-components/icons/AboutIcon.d.ts +1 -1
  188. package/esm/typings/src/book-components/icons/AttachmentIcon.d.ts +1 -1
  189. package/esm/typings/src/book-components/icons/CameraIcon.d.ts +1 -1
  190. package/esm/typings/src/book-components/icons/DownloadIcon.d.ts +1 -1
  191. package/esm/typings/src/book-components/icons/MenuIcon.d.ts +1 -1
  192. package/esm/typings/src/book-components/icons/SaveIcon.d.ts +1 -1
  193. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +22 -12
  194. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentsDatabaseSchema.d.ts +27 -15
  195. package/esm/typings/src/commitments/DICTIONARY/DICTIONARY.d.ts +46 -0
  196. package/esm/typings/src/commitments/index.d.ts +2 -1
  197. package/esm/typings/src/llm-providers/_common/utils/count-total-usage/countUsage.d.ts +1 -1
  198. package/esm/typings/src/llm-providers/_multiple/MultipleLlmExecutionTools.d.ts +6 -2
  199. package/esm/typings/src/llm-providers/agent/Agent.d.ts +6 -1
  200. package/esm/typings/src/llm-providers/agent/AgentLlmExecutionTools.d.ts +1 -1
  201. package/esm/typings/src/llm-providers/ollama/OllamaExecutionTools.d.ts +1 -1
  202. package/esm/typings/src/llm-providers/openai/createOpenAiCompatibleExecutionTools.d.ts +1 -1
  203. package/esm/typings/src/llm-providers/remote/RemoteLlmExecutionTools.d.ts +1 -0
  204. package/esm/typings/src/remote-server/ui/ServerApp.d.ts +1 -1
  205. package/esm/typings/src/search-engines/SearchEngine.d.ts +9 -0
  206. package/esm/typings/src/search-engines/SearchResult.d.ts +18 -0
  207. package/esm/typings/src/search-engines/bing/BingSearchEngine.d.ts +15 -0
  208. package/esm/typings/src/search-engines/dummy/DummySearchEngine.d.ts +15 -0
  209. package/esm/typings/src/types/Message.d.ts +49 -0
  210. package/esm/typings/src/types/ModelRequirements.d.ts +38 -14
  211. package/esm/typings/src/types/typeAliases.d.ts +23 -1
  212. package/esm/typings/src/utils/color/utils/colorToDataUrl.d.ts +2 -1
  213. package/esm/typings/src/utils/environment/$detectRuntimeEnvironment.d.ts +4 -4
  214. package/esm/typings/src/utils/environment/$isRunningInBrowser.d.ts +1 -1
  215. package/esm/typings/src/utils/environment/$isRunningInJest.d.ts +1 -1
  216. package/esm/typings/src/utils/environment/$isRunningInNode.d.ts +1 -1
  217. package/esm/typings/src/utils/environment/$isRunningInWebWorker.d.ts +1 -1
  218. package/esm/typings/src/utils/markdown/extractAllBlocksFromMarkdown.d.ts +2 -2
  219. package/esm/typings/src/utils/markdown/extractOneBlockFromMarkdown.d.ts +2 -2
  220. package/esm/typings/src/utils/random/$randomAgentPersona.d.ts +3 -2
  221. package/esm/typings/src/utils/random/$randomBase58.d.ts +12 -0
  222. package/esm/typings/src/version.d.ts +1 -1
  223. package/package.json +1 -1
  224. package/umd/index.umd.js +1542 -1338
  225. package/umd/index.umd.js.map +1 -1
  226. package/apps/agents-server/package-lock.json +0 -27
  227. package/apps/agents-server/public/fonts/download-font.js +0 -22
  228. package/apps/agents-server/src/components/PrintButton/PrintButton.tsx +0 -18
  229. package/esm/typings/src/book-2.0/utils/generateGravatarUrl.d.ts +0 -10
@@ -1,26 +1,28 @@
1
1
  // Utility to generate content for robots.txt, security.txt, and humans.txt [DRY]
2
2
 
3
- import { NEXT_PUBLIC_SITE_URL } from '@/config';
3
+ import { $provideServer } from '@/src/tools/$provideServer';
4
4
 
5
- // Get base URL from environment or config
6
- const baseUrl = NEXT_PUBLIC_SITE_URL?.href || process.env.PUBLIC_URL || 'https://ptbk.io';
7
-
8
- export function generateRobotsTxt(): string {
9
- return ['User-agent: *', `Sitemap: ${baseUrl}sitemap.xml`, ''].join('\n');
5
+ export async function generateRobotsTxt(): Promise<string> {
6
+ const { publicUrl } = await $provideServer();
7
+ return ['User-agent: *', `Sitemap: ${publicUrl.href}sitemap.xml`, ''].join('\n');
10
8
  }
11
9
 
12
- export function generateSecurityTxt(): string {
10
+ export async function generateSecurityTxt(): Promise<string> {
11
+ const { publicUrl } = await $provideServer();
13
12
  // See https://securitytxt.org/ for more fields
14
13
  return [
15
14
  `Contact: mailto:security@ptbk.io`,
16
15
  `Expires: ${new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString().split('T')[0]}`,
17
- `Canonical: ${baseUrl}security.txt`,
16
+ `Canonical: ${publicUrl.href}security.txt`,
18
17
  '',
19
18
  ].join('\n');
20
19
  }
21
20
 
22
- export function generateHumansTxt(): string {
23
- return ['/* TEAM */', 'Developer: Promptbook Team', `Site: https://ptbk.io`, `Instance: ${baseUrl}`].join('\n');
21
+ export async function generateHumansTxt(): Promise<string> {
22
+ const { publicUrl } = await $provideServer();
23
+ return ['/* TEAM */', 'Developer: Promptbook Team', `Site: https://ptbk.io`, `Instance: ${publicUrl.href}`].join(
24
+ '\n',
25
+ );
24
26
  }
25
27
 
26
28
  /**
@@ -1,6 +1,6 @@
1
1
  // Utility to append ?headless param if present in current URL
2
- import { usePathname, useSearchParams } from 'next/navigation';
3
2
  import Link, { LinkProps } from 'next/link';
3
+ import { useSearchParams } from 'next/navigation';
4
4
  import { useMemo } from 'react';
5
5
 
6
6
  // Returns true if ?headless is present in current search params
@@ -18,7 +18,11 @@ export function appendHeadlessParam(href: string, isHeadless: boolean): string {
18
18
  }
19
19
 
20
20
  // Custom Link that preserves headless param
21
- export function HeadlessLink({ href, children, ...rest }: LinkProps & { children: React.ReactNode } & React.AnchorHTMLAttributes<HTMLAnchorElement>) {
21
+ export function HeadlessLink({
22
+ href,
23
+ children,
24
+ ...rest
25
+ }: LinkProps & { children: React.ReactNode } & React.AnchorHTMLAttributes<HTMLAnchorElement>) {
22
26
  const isHeadless = useIsHeadless();
23
27
  const finalHref = useMemo(() => appendHeadlessParam(String(href), isHeadless), [href, isHeadless]);
24
28
  return (
@@ -28,7 +32,7 @@ export function HeadlessLink({ href, children, ...rest }: LinkProps & { children
28
32
  );
29
33
  }
30
34
 
31
- import { useRouter } from "next/navigation";
35
+ import { useRouter } from 'next/navigation';
32
36
 
33
37
  // Helper for router.push
34
38
  export function pushWithHeadless(router: ReturnType<typeof useRouter>, href: string, isHeadless: boolean) {
@@ -15,4 +15,5 @@ type string_table_name = keyof AgentsServerDatabase['public']['Tables'];
15
15
  export async function $getTableName<TTable extends string_table_name>(tableName: TTable): Promise<TTable> {
16
16
  const { tablePrefix } = await $provideServer();
17
17
  return `${tablePrefix}${tableName}` as TTable;
18
+ // <- TODO: [🏧] DRY
18
19
  }
@@ -1,6 +1,6 @@
1
- import { AgentsDatabaseSchema } from '@promptbook-local/types';
2
1
  import { $isRunningInBrowser } from '@promptbook-local/utils';
3
2
  import { createClient, SupabaseClient } from '@supabase/supabase-js';
3
+ import { AgentsServerDatabase } from './schema';
4
4
 
5
5
  /**
6
6
  * Internal cache for `$provideSupabaseForBrowser`
@@ -8,7 +8,7 @@ import { createClient, SupabaseClient } from '@supabase/supabase-js';
8
8
  * @private
9
9
  * @singleton
10
10
  */
11
- let supabase: SupabaseClient<AgentsDatabaseSchema>;
11
+ let supabase: SupabaseClient<AgentsServerDatabase>;
12
12
 
13
13
  /**
14
14
  * Get supabase client
@@ -27,7 +27,7 @@ export function $provideSupabaseForBrowser(): typeof supabase {
27
27
 
28
28
  if (!supabase) {
29
29
  // Create a single supabase client for interacting with your database
30
- supabase = createClient<AgentsDatabaseSchema>(
30
+ supabase = createClient<AgentsServerDatabase>(
31
31
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
32
32
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
33
33
  );
@@ -18,7 +18,7 @@ let supabase: SupabaseClient<AgentsServerDatabase>;
18
18
  *
19
19
  * @returns instance of supabase client
20
20
  */
21
- export function $provideSupabaseForServer(): typeof supabase {
21
+ export function $provideSupabaseForServer(): SupabaseClient<AgentsServerDatabase> {
22
22
  if (!$isRunningInNode()) {
23
23
  throw new Error(
24
24
  'Function `$provideSupabaseForServer` can not be used in browser, use `$provideSupabaseForBrowser` instead.',
@@ -1,6 +1,6 @@
1
- import { AgentsDatabaseSchema } from '@promptbook-local/types';
2
1
  import { $isRunningInWebWorker } from '@promptbook-local/utils';
3
2
  import { createClient, SupabaseClient } from '@supabase/supabase-js';
3
+ import { AgentsServerDatabase } from './schema';
4
4
 
5
5
  /**
6
6
  * Internal cache for `$provideSupabaseForWorker`
@@ -8,7 +8,7 @@ import { createClient, SupabaseClient } from '@supabase/supabase-js';
8
8
  * @private
9
9
  * @singleton
10
10
  */
11
- let supabase: SupabaseClient<AgentsDatabaseSchema>;
11
+ let supabase: SupabaseClient<AgentsServerDatabase>;
12
12
 
13
13
  /**
14
14
  * Get supabase client
@@ -27,7 +27,7 @@ export function $provideSupabaseForWorker(): typeof supabase {
27
27
 
28
28
  if (!supabase) {
29
29
  // Create a single supabase client for interacting with your database
30
- supabase = createClient<AgentsDatabaseSchema>(
30
+ supabase = createClient<AgentsServerDatabase>(
31
31
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
32
32
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
33
33
  );
@@ -38,7 +38,13 @@ export const metadataDefaults = [
38
38
  type: 'TEXT',
39
39
  },
40
40
  {
41
- key: 'IS_VOICE_CALLING_ENABLED',
41
+ key: 'SHOW_FEDERATED_SERVERS_PUBLICLY',
42
+ value: 'false',
43
+ note: 'Whether to show federated servers and their agents to anonymous users. When false, federated servers are only visible to authenticated users.',
44
+ type: 'BOOLEAN',
45
+ },
46
+ {
47
+ key: 'IS_EXPERIMENTAL_VOICE_CALLING_ENABLED',
42
48
  value: 'false',
43
49
  note: 'Enable or disable voice calling features for agents. When disabled, voice API endpoints will return 403 Forbidden.',
44
50
  type: 'BOOLEAN',
@@ -67,6 +73,18 @@ export const metadataDefaults = [
67
73
  note: 'Language for generating new agent names. Possible values: ENGLISH, CZECH.',
68
74
  type: 'TEXT_SINGLE_LINE',
69
75
  },
76
+ {
77
+ key: 'ADMIN_EMAIL',
78
+ value: 'support@ptbk.io',
79
+ note: 'Administrator email address used for password reset and user registration requests.',
80
+ type: 'TEXT_SINGLE_LINE',
81
+ },
82
+ {
83
+ key: 'DEFAULT_AGENT_VISIBILITY',
84
+ value: 'PRIVATE',
85
+ note: 'Default visibility for new agents. Can be PUBLIC or PRIVATE.',
86
+ type: 'TEXT_SINGLE_LINE',
87
+ },
70
88
  ] as const satisfies ReadonlyArray<{
71
89
  key: string;
72
90
  value: string;
@@ -8,13 +8,34 @@ dotenv.config();
8
8
  async function migrate() {
9
9
  console.info('🚀 Starting database migration');
10
10
 
11
+ // Parse CLI arguments for --only flag
12
+ const args = process.argv.slice(2);
13
+ let onlyPrefixes: string[] | null = null;
14
+
15
+ for (let i = 0; i < args.length; i++) {
16
+ if (args[i] === '--only' && args[i + 1]) {
17
+ onlyPrefixes = args[i + 1]
18
+ .split(',')
19
+ .map((p) => p.trim())
20
+ .filter((p) => p !== '');
21
+ break;
22
+ } else if (args[i]?.startsWith('--only=')) {
23
+ onlyPrefixes = args[i]
24
+ .substring('--only='.length)
25
+ .split(',')
26
+ .map((p) => p.trim())
27
+ .filter((p) => p !== '');
28
+ break;
29
+ }
30
+ }
31
+
11
32
  // 1. Get configuration
12
33
  const prefixesEnv = process.env.SUPABASE_MIGRATION_PREFIXES;
13
34
  if (!prefixesEnv) {
14
35
  console.warn('⚠️ SUPABASE_MIGRATION_PREFIXES is not defined. Skipping migration.');
15
36
  return;
16
37
  }
17
- const prefixes = prefixesEnv
38
+ let prefixes = prefixesEnv
18
39
  .split(',')
19
40
  .map((p) => p.trim())
20
41
  .filter((p) => p !== '');
@@ -24,6 +45,18 @@ async function migrate() {
24
45
  return;
25
46
  }
26
47
 
48
+ // Filter prefixes if --only flag is provided
49
+ if (onlyPrefixes !== null) {
50
+ const invalidPrefixes = onlyPrefixes.filter((p) => !prefixes.includes(p));
51
+ if (invalidPrefixes.length > 0) {
52
+ console.error(`❌ Invalid prefixes specified in --only: ${invalidPrefixes.join(', ')}`);
53
+ console.error(` Available prefixes: ${prefixes.join(', ')}`);
54
+ process.exit(1);
55
+ }
56
+ prefixes = onlyPrefixes;
57
+ console.info(`🎯 Running migrations only for: ${prefixes.join(', ')}`);
58
+ }
59
+
27
60
  const connectionString = process.env.POSTGRES_URL || process.env.DATABASE_URL;
28
61
  if (!connectionString) {
29
62
  console.error('❌ POSTGRES_URL or DATABASE_URL is not defined.');
@@ -1,6 +1,4 @@
1
- -- Note: This is primary source of truth for the database schema
2
- -- In future we want to be compatible with more then Supabase so we keep SQL as main schema definition
3
- -- To update, search for [💽]
1
+
4
2
 
5
3
 
6
4
  CREATE TABLE IF NOT EXISTS "prefix_Agent" (
@@ -1,6 +1,4 @@
1
- -- Note: This is primary source of truth for the database schema
2
- -- In future we want to be compatible with more then Supabase so we keep SQL as main schema definition
3
- -- To update, search for [💽]
1
+
4
2
 
5
3
 
6
4
  CREATE TABLE IF NOT EXISTS "prefix_Metadata" (
@@ -0,0 +1,3 @@
1
+
2
+ ALTER TABLE "prefix_Agent" ADD COLUMN "permanentId" TEXT;
3
+ CREATE UNIQUE INDEX "prefix_Agent_permanentId_key" ON "prefix_Agent"("permanentId");
@@ -0,0 +1 @@
1
+ ALTER TABLE "prefix_Agent" ADD COLUMN "deletedAt" TEXT;
@@ -0,0 +1,19 @@
1
+ CREATE TABLE IF NOT EXISTS "prefix_Image" (
2
+ "id" BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
3
+ "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
4
+ "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
5
+
6
+ "filename" TEXT NOT NULL,
7
+ "prompt" TEXT NOT NULL,
8
+ "cdnUrl" TEXT NOT NULL,
9
+ "cdnKey" TEXT NOT NULL
10
+ );
11
+
12
+ CREATE UNIQUE INDEX IF NOT EXISTS "prefix_Image_filename_idx" ON "prefix_Image" ("filename");
13
+
14
+ ALTER TABLE "prefix_Image" ENABLE ROW LEVEL SECURITY;
15
+
16
+ COMMENT ON COLUMN "prefix_Image"."filename" IS 'The original filename requested (e.g., cat-sitting-on-keyboard.png)';
17
+ COMMENT ON COLUMN "prefix_Image"."prompt" IS 'The normalized prompt used to generate the image';
18
+ COMMENT ON COLUMN "prefix_Image"."cdnUrl" IS 'The full URL of the uploaded image in CDN';
19
+ COMMENT ON COLUMN "prefix_Image"."cdnKey" IS 'The key used to identify the image in CDN storage';
@@ -0,0 +1 @@
1
+ ALTER TABLE "prefix_Agent" ADD COLUMN "visibility" TEXT NOT NULL DEFAULT 'PRIVATE' CHECK ("visibility" IN ('PUBLIC', 'PRIVATE'));
@@ -0,0 +1,20 @@
1
+ CREATE TABLE IF NOT EXISTS "prefix_File" (
2
+ "id" BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
3
+ "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
4
+
5
+ "userId" BIGINT REFERENCES "prefix_User"("id"),
6
+ "fileName" TEXT NOT NULL,
7
+ "fileSize" BIGINT NOT NULL,
8
+ "fileType" TEXT NOT NULL,
9
+ "cdnUrl" TEXT NOT NULL,
10
+ "purpose" TEXT NOT NULL
11
+ );
12
+
13
+ ALTER TABLE "prefix_File" ENABLE ROW LEVEL SECURITY;
14
+
15
+ COMMENT ON COLUMN "prefix_File"."userId" IS 'Reference to the user who uploaded the file';
16
+ COMMENT ON COLUMN "prefix_File"."fileName" IS 'Original name of the uploaded file';
17
+ COMMENT ON COLUMN "prefix_File"."fileSize" IS 'Size of the file in bytes';
18
+ COMMENT ON COLUMN "prefix_File"."fileType" IS 'MIME type of the file';
19
+ COMMENT ON COLUMN "prefix_File"."cdnUrl" IS 'Public URL of the file in CDN';
20
+ COMMENT ON COLUMN "prefix_File"."purpose" IS 'Purpose of the upload (e.g. KNOWLEDGE, SERVER_FAVICON_URL)';
@@ -0,0 +1,13 @@
1
+ -- Add status column to track file upload progress
2
+ ALTER TABLE "prefix_File" ADD COLUMN IF NOT EXISTS "status" TEXT NOT NULL DEFAULT 'COMPLETED';
3
+
4
+ -- Add check constraint for valid status values
5
+ -- ALTER TABLE "prefix_File" ADD CONSTRAINT "File_status_check" CHECK ("status" IN ('UPLOADING', 'COMPLETED', 'FAILED'));
6
+
7
+ -- Drop the column cdnUrl if it exists
8
+ ALTER TABLE "prefix_File" DROP COLUMN IF EXISTS "cdnUrl";
9
+
10
+
11
+ -- Add nullable columns storageUrl and shortUrl
12
+ ALTER TABLE "prefix_File" ADD COLUMN IF NOT EXISTS "storageUrl" TEXT NULL;
13
+ ALTER TABLE "prefix_File" ADD COLUMN IF NOT EXISTS "shortUrl" TEXT NULL;
@@ -0,0 +1,42 @@
1
+
2
+ -- Table: Message
3
+ CREATE TABLE IF NOT EXISTS "prefix_Message" (
4
+ "id" BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
5
+ "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
6
+ "channel" TEXT NOT NULL,
7
+ "direction" TEXT NOT NULL,
8
+ "sender" JSONB NOT NULL,
9
+ "recipients" JSONB,
10
+ "content" TEXT NOT NULL,
11
+ "threadId" TEXT,
12
+ "metadata" JSONB
13
+ );
14
+
15
+ COMMENT ON TABLE "prefix_Message" IS 'A generic message structure for various communication channels';
16
+ COMMENT ON COLUMN "prefix_Message"."channel" IS 'The communication channel of the message (e.g. EMAIL, PROMPTBOOK_CHAT)';
17
+ COMMENT ON COLUMN "prefix_Message"."direction" IS 'Is the message send from the Promptbook or to the Promptbook';
18
+ COMMENT ON COLUMN "prefix_Message"."sender" IS 'Who sent the message';
19
+ COMMENT ON COLUMN "prefix_Message"."recipients" IS 'Who are the recipients of the message';
20
+ COMMENT ON COLUMN "prefix_Message"."content" IS 'The content of the message as markdown';
21
+ COMMENT ON COLUMN "prefix_Message"."threadId" IS 'The thread identifier the message belongs to';
22
+
23
+
24
+ -- Table: MessageSendAttempt
25
+ CREATE TABLE IF NOT EXISTS "prefix_MessageSendAttempt" (
26
+ "id" BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
27
+ "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
28
+
29
+ "messageId" BIGINT NOT NULL REFERENCES "prefix_Message"("id") ON DELETE CASCADE,
30
+ "providerName" TEXT NOT NULL,
31
+ "isSuccessful" BOOLEAN NOT NULL,
32
+ "raw" JSONB
33
+ );
34
+
35
+ COMMENT ON TABLE "prefix_MessageSendAttempt" IS 'Stores each attempt to send the message';
36
+ COMMENT ON COLUMN "prefix_MessageSendAttempt"."messageId" IS 'The message that was attempted to be sent';
37
+ COMMENT ON COLUMN "prefix_MessageSendAttempt"."providerName" IS 'The name of the provider used for sending';
38
+ COMMENT ON COLUMN "prefix_MessageSendAttempt"."isSuccessful" IS 'Whether the attempt was successful';
39
+ COMMENT ON COLUMN "prefix_MessageSendAttempt"."raw" IS 'Raw response or error from the provider';
40
+
41
+ ALTER TABLE "prefix_Message" ENABLE ROW LEVEL SECURITY;
42
+ ALTER TABLE "prefix_MessageSendAttempt" ENABLE ROW LEVEL SECURITY;
@@ -0,0 +1,15 @@
1
+ CREATE TABLE IF NOT EXISTS "prefix_GenerationLock" (
2
+ "id" BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
3
+ "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
4
+ "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
5
+ "lockKey" TEXT NOT NULL,
6
+ "expiresAt" TIMESTAMP WITH TIME ZONE NOT NULL
7
+ );
8
+
9
+ CREATE UNIQUE INDEX IF NOT EXISTS "prefix_GenerationLock_lockKey_idx" ON "prefix_GenerationLock" ("lockKey");
10
+
11
+ ALTER TABLE "prefix_GenerationLock" ENABLE ROW LEVEL SECURITY;
12
+
13
+ COMMENT ON TABLE "prefix_GenerationLock" IS 'Locks to prevent concurrent expensive operations like image generation';
14
+ COMMENT ON COLUMN "prefix_GenerationLock"."lockKey" IS 'Unique key for the lock (e.g. agent-avatar-<hash>)';
15
+ COMMENT ON COLUMN "prefix_GenerationLock"."expiresAt" IS 'When the lock expires and can be overridden';
@@ -0,0 +1,12 @@
1
+ CREATE TABLE IF NOT EXISTS "prefix_OpenAiAssistantCache" (
2
+ "id" BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
3
+ "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
4
+ "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
5
+
6
+ "agentHash" TEXT NOT NULL,
7
+ "assistantId" TEXT NOT NULL
8
+ );
9
+
10
+ CREATE UNIQUE INDEX IF NOT EXISTS "prefix_OpenAiAssistantCache_agentHash_idx" ON "prefix_OpenAiAssistantCache" ("agentHash");
11
+
12
+ ALTER TABLE "prefix_OpenAiAssistantCache" ENABLE ROW LEVEL SECURITY;
@@ -0,0 +1,29 @@
1
+ -- Backfill permanentId in Agent table if missing
2
+ UPDATE "prefix_Agent"
3
+ SET "permanentId" = gen_random_uuid()::text
4
+ WHERE "permanentId" IS NULL;
5
+
6
+ -- Add permanentId column to AgentHistory
7
+ ALTER TABLE "prefix_AgentHistory" ADD COLUMN "permanentId" TEXT;
8
+
9
+ -- Backfill permanentId from Agent table
10
+ UPDATE "prefix_AgentHistory" ah
11
+ SET "permanentId" = a."permanentId"
12
+ FROM "prefix_Agent" a
13
+ WHERE ah."agentName" = a."agentName";
14
+
15
+ -- Make permanentId NOT NULL
16
+ ALTER TABLE "prefix_AgentHistory" ALTER COLUMN "permanentId" SET NOT NULL;
17
+
18
+ -- Drop old foreign key on agentName
19
+ ALTER TABLE "prefix_AgentHistory" DROP CONSTRAINT "prefix_AgentHistory_agentName_fkey";
20
+
21
+ -- Add new foreign key on permanentId referencing Agent(permanentId)
22
+ ALTER TABLE "prefix_AgentHistory"
23
+ ADD CONSTRAINT "prefix_AgentHistory_permanentId_fkey"
24
+ FOREIGN KEY ("permanentId")
25
+ REFERENCES "prefix_Agent"("permanentId")
26
+ ON DELETE CASCADE;
27
+
28
+ -- Add index for permanentId
29
+ CREATE INDEX "prefix_AgentHistory_permanentId_idx" ON "prefix_AgentHistory" ("permanentId");
@@ -0,0 +1,5 @@
1
+ ALTER TABLE "prefix_Image" ADD COLUMN "agentId" BIGINT REFERENCES "prefix_Agent"("id") ON DELETE CASCADE;
2
+ ALTER TABLE "prefix_Image" ADD COLUMN "purpose" TEXT CHECK ("purpose" IN ('AVATAR', 'TESTING'));
3
+
4
+ COMMENT ON COLUMN "prefix_Image"."agentId" IS 'The agent this image belongs to (nullable for testing images)';
5
+ COMMENT ON COLUMN "prefix_Image"."purpose" IS 'The purpose of the image (AVATAR or TESTING)';
@@ -0,0 +1,5 @@
1
+ -- Add agentId column to associate files with agents
2
+ ALTER TABLE "prefix_File" ADD COLUMN IF NOT EXISTS "agentId" INTEGER NULL;
3
+
4
+ -- Add foreign key constraint to Agent table
5
+ ALTER TABLE "prefix_File" ADD CONSTRAINT "File_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "prefix_Agent" ("id") ON DELETE SET NULL;