@promptbook/cli 0.114.0-1 → 0.114.0-3

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 (199) hide show
  1. package/README.md +16 -15
  2. package/apps/agents-server/next.config.ts +11 -0
  3. package/apps/agents-server/package.json +6 -4
  4. package/apps/agents-server/playwright.config.ts +28 -38
  5. package/apps/agents-server/scripts/build-agents-server.js +62 -0
  6. package/apps/agents-server/scripts/build-e2e.js +38 -0
  7. package/apps/agents-server/scripts/ensure-root-dependencies.js +86 -0
  8. package/apps/agents-server/scripts/prerender-homepage.js +1 -1
  9. package/apps/agents-server/scripts/run-e2e-tests.js +34 -0
  10. package/apps/agents-server/scripts/run-npm.js +42 -0
  11. package/apps/agents-server/src/app/admin/email-server/page.tsx +14 -6
  12. package/apps/agents-server/src/app/api/elevenlabs/tts/route.ts +3 -3
  13. package/apps/agents-server/src/app/api/onboarding/book/route.ts +7 -6
  14. package/apps/agents-server/src/app/layout.tsx +6 -0
  15. package/apps/agents-server/src/app/superadmin/servers/ServersRegistryTable.tsx +105 -102
  16. package/apps/agents-server/src/app/superadmin/servers/useServersRegistryState.ts +15 -7
  17. package/apps/agents-server/src/components/AgentProjectDnsInstructions/AgentProjectDnsInstructions.tsx +11 -11
  18. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ManGoBookEditor.tsx +82 -0
  19. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/WizardShell.tsx +2 -2
  20. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/BookStep.tsx +13 -16
  21. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/ZadaniStep.tsx +4 -4
  22. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/config/bookSections.ts +23 -16
  23. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/lib/bookSource.ts +54 -0
  24. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/bookService.ts +15 -8
  25. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/createManGoAgentSource.ts +3 -37
  26. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/createManGoOpenEditorRequest.ts +1 -1
  27. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/state/OnboardingProvider.tsx +2 -2
  28. package/apps/agents-server/src/components/UsersList/CreateUserDialog.tsx +13 -22
  29. package/apps/agents-server/src/components/UsersList/PasswordGeneratorDialog.tsx +216 -0
  30. package/apps/agents-server/src/components/UsersList/UsersList.tsx +16 -11
  31. package/apps/agents-server/src/components/UsersList/generateSecurePassword.ts +112 -24
  32. package/apps/agents-server/src/components/UsersList/userDialogClassNames.ts +11 -0
  33. package/apps/agents-server/src/languages/ServerTranslationKeys.ts +11 -0
  34. package/apps/agents-server/src/languages/translations/czech.yaml +11 -0
  35. package/apps/agents-server/src/languages/translations/english.yaml +11 -0
  36. package/apps/agents-server/src/utils/agentProjects/agentProjectHrefs.ts +11 -0
  37. package/apps/agents-server/src/utils/agentProjects/createAgentProjectDnsRecords.ts +53 -7
  38. package/apps/agents-server/src/utils/agentProjects/createAgentProjectMarkdownReferences.ts +37 -27
  39. package/apps/agents-server/src/utils/manGoOnboarding/manGoOnboardingAgentBooks.ts +2 -13
  40. package/apps/agents-server/src/utils/manGoOnboarding/manGoOnboardingAgentRuntime.ts +21 -73
  41. package/apps/agents-server/src/utils/stalwart/createEmailDnsInstructions.ts +9 -5
  42. package/apps/agents-server/src/utils/stalwart/readStalwartEmailSnapshot.ts +23 -5
  43. package/apps/agents-server/src/utils/stalwart/stalwartBootstrap.ts +2 -1
  44. package/apps/agents-server/src/utils/stalwart/stalwartMailBridge.ts +7 -0
  45. package/apps/agents-server/tests/e2e/e2eEnvironment.cjs +49 -0
  46. package/esm/index.es.js +1105 -273
  47. package/esm/index.es.js.map +1 -1
  48. package/esm/scripts/run-codex-prompts/common/runGoScript/scriptExecutionLog.d.ts +7 -0
  49. package/esm/scripts/run-codex-prompts/git/coderGitSync.d.ts +43 -0
  50. package/esm/scripts/run-codex-prompts/git/commitChanges.d.ts +3 -0
  51. package/esm/scripts/run-codex-prompts/main/resolvePromptRunner.d.ts +8 -1
  52. package/esm/scripts/run-codex-prompts/ping/buildCoderPingPrompt.d.ts +20 -0
  53. package/esm/scripts/run-codex-prompts/ping/extractCoderPingAnswer.d.ts +9 -0
  54. package/esm/scripts/run-codex-prompts/ping/pingCoderHarness.d.ts +23 -0
  55. package/esm/scripts/run-codex-prompts/ping/printCoderPingResult.d.ts +5 -0
  56. package/esm/scripts/run-codex-prompts/prompts/findNextTodoPrompt.d.ts +2 -1
  57. package/esm/scripts/run-codex-prompts/prompts/isPromptCompatibleWithRunner.d.ts +27 -0
  58. package/esm/scripts/run-codex-prompts/prompts/listRunnablePrompts.d.ts +2 -1
  59. package/esm/scripts/run-codex-prompts/prompts/listUpcomingTasks.d.ts +2 -1
  60. package/esm/scripts/run-codex-prompts/prompts/replacePromptTodoStatusLine.d.ts +7 -0
  61. package/esm/scripts/run-codex-prompts/testing/TestBeforeMode.d.ts +16 -0
  62. package/esm/scripts/run-codex-prompts/testing/createTestBeforeRepairPrompt.d.ts +9 -0
  63. package/esm/scripts/run-codex-prompts/testing/limitTestOutput.d.ts +4 -0
  64. package/esm/scripts/run-codex-prompts/testing/runPromptTestCommand.d.ts +1 -2
  65. package/esm/scripts/run-codex-prompts/testing/runTestBefore.d.ts +24 -0
  66. package/esm/scripts/run-codex-prompts/ui/buildRunUiFrameShared.d.ts +1 -0
  67. package/esm/scripts/verify-prompts/verify-prompts.d.ts +5 -0
  68. package/esm/src/book-2.0/book-language-documentation/BookLanguageManualDictionary.d.ts +1 -15
  69. package/esm/src/book-2.0/book-language-documentation/getBookLanguageManualCommitmentGroups.d.ts +1 -1
  70. package/esm/src/book-2.0/book-language-documentation/renderCommitmentCatalogSection.d.ts +0 -4
  71. package/esm/src/book-components/Chat/utils/$provideServerDomWindow.d.ts +11 -0
  72. package/esm/src/book-components/Chat/utils/renderMarkdown.d.ts +7 -0
  73. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/createAgentsServerRuntimeEnvironment.d.ts +7 -0
  74. package/esm/src/cli/cli-commands/coder/agentCodingFile.d.ts +2 -3
  75. package/esm/src/cli/cli-commands/coder/ping.d.ts +10 -0
  76. package/esm/src/cli/cli-commands/coder/ping.test.d.ts +1 -0
  77. package/esm/src/cli/cli-commands/coder.d.ts +1 -0
  78. package/esm/src/cli/cli-commands/common/coderGitSyncCliOptions.d.ts +34 -0
  79. package/esm/src/cli/cli-commands/common/coderGitSyncCliOptions.test.d.ts +1 -0
  80. package/esm/src/cli/common/loadPromptsModule.d.ts +16 -0
  81. package/esm/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.d.ts +1 -1
  82. package/esm/src/llm-providers/azure-openai/AzureOpenAiExecutionTools.d.ts +1 -1
  83. package/esm/src/llm-providers/openai/OpenAiAgentKitExecutionTools.d.ts +1 -1
  84. package/esm/src/llm-providers/openai/OpenAiAgentKitExecutionToolsToolBuilder.d.ts +1 -1
  85. package/esm/src/llm-providers/openai/OpenAiAssistantExecutionToolsStreamRunner.d.ts +1 -1
  86. package/esm/src/llm-providers/openai/OpenAiAssistantExecutionToolsToolRunner.d.ts +1 -1
  87. package/esm/src/llm-providers/openai/OpenAiCompatibleNonChatPromptCaller.d.ts +1 -1
  88. package/esm/src/llm-providers/openai/OpenAiCompatibleRequestManager.d.ts +1 -1
  89. package/esm/src/llm-providers/openai/utils/callOpenAiCompatibleChatModel.d.ts +1 -1
  90. package/esm/src/llm-providers/openai/utils/loadOpenAiAgentsModule.d.ts +203 -0
  91. package/esm/src/llm-providers/openai/utils/uploadFilesToOpenAi.d.ts +1 -1
  92. package/esm/src/utils/misc/createLazyModuleLoader.d.ts +14 -0
  93. package/esm/src/version.d.ts +1 -1
  94. package/package.json +1 -1
  95. package/src/book-2.0/book-language-documentation/BookLanguageManualDictionary.ts +1 -15
  96. package/src/book-2.0/book-language-documentation/bookLanguageDocumentationExamples.ts +1 -2
  97. package/src/book-2.0/book-language-documentation/createStandaloneBookLanguageMarkdown.ts +92 -32
  98. package/src/book-2.0/book-language-documentation/czechBookLanguageManualDictionary.ts +16 -39
  99. package/src/book-2.0/book-language-documentation/englishBookLanguageManualDictionary.ts +16 -36
  100. package/src/book-2.0/book-language-documentation/getBookLanguageManualCommitmentGroups.ts +9 -1
  101. package/src/book-2.0/book-language-documentation/renderCommitmentCatalogSection.ts +4 -51
  102. package/src/book-2.0/book-language-documentation/renderGroupedCommitmentDocumentationMarkdown.ts +291 -4
  103. package/src/book-3.0/LiteAgent.ts +11 -9
  104. package/src/book-components/Chat/utils/$provideServerDomWindow.ts +77 -0
  105. package/src/book-components/Chat/utils/renderMarkdown.ts +135 -32
  106. package/src/cli/cli-commands/agents-server/buildAgentsServer/createAgentsServerRuntimeEnvironment.ts +14 -0
  107. package/src/cli/cli-commands/agents-server/buildAgentsServer/ensureAgentsServerBuild.ts +1 -0
  108. package/src/cli/cli-commands/agents-server/startAgentsServer/createLocalAgentRunOptions.ts +1 -0
  109. package/src/cli/cli-commands/coder/add.ts +40 -12
  110. package/src/cli/cli-commands/coder/agentCodingFile.ts +6 -129
  111. package/src/cli/cli-commands/coder/generate-boilerplates.ts +31 -5
  112. package/src/cli/cli-commands/coder/getDefaultCoderPackageJsonScripts.ts +1 -1
  113. package/src/cli/cli-commands/coder/init.ts +27 -1
  114. package/src/cli/cli-commands/coder/initializeCoderProjectConfiguration.ts +1 -4
  115. package/src/cli/cli-commands/coder/ping.ts +72 -0
  116. package/src/cli/cli-commands/coder/run.ts +25 -2
  117. package/src/cli/cli-commands/coder/verify.ts +27 -12
  118. package/src/cli/cli-commands/coder.ts +4 -0
  119. package/src/cli/cli-commands/common/coderGitSyncCliOptions.ts +78 -0
  120. package/src/cli/cli-commands/run/prepareRunCommandResources.ts +2 -1
  121. package/src/cli/cli-commands/run/resolveRunInputParameters.ts +2 -1
  122. package/src/cli/cli-commands/runInteractiveChatbot.ts +2 -1
  123. package/src/cli/common/$provideLlmToolsForCli.ts +2 -1
  124. package/src/cli/common/loadPromptsModule.ts +13 -0
  125. package/src/conversion/archive/loadArchive.ts +2 -1
  126. package/src/conversion/archive/loadJsZipModule.ts +10 -0
  127. package/src/conversion/archive/saveArchive.ts +2 -1
  128. package/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.ts +13 -1
  129. package/src/llm-providers/azure-openai/AzureOpenAiExecutionTools.ts +13 -1
  130. package/src/llm-providers/openai/OpenAiAgentKitExecutionTools.ts +6 -2
  131. package/src/llm-providers/openai/OpenAiAgentKitExecutionToolsToolBuilder.ts +7 -5
  132. package/src/llm-providers/openai/OpenAiAssistantExecutionTools.ts +1 -1
  133. package/src/llm-providers/openai/OpenAiAssistantExecutionToolsStreamRunner.ts +1 -1
  134. package/src/llm-providers/openai/OpenAiAssistantExecutionToolsToolRunner.ts +1 -1
  135. package/src/llm-providers/openai/OpenAiCompatibleNonChatPromptCaller.ts +1 -1
  136. package/src/llm-providers/openai/OpenAiCompatibleRequestManager.ts +12 -1
  137. package/src/llm-providers/openai/utils/callOpenAiCompatibleChatModel.ts +1 -1
  138. package/src/llm-providers/openai/utils/loadOpenAiAgentsModule.ts +11 -0
  139. package/src/llm-providers/openai/utils/uploadFilesToOpenAi.ts +1 -1
  140. package/src/other/templates/getTemplatesPipelineCollection.ts +731 -923
  141. package/src/remote-server/createRemoteClient.ts +12 -1
  142. package/src/scrapers/website/WebsiteScraper.ts +22 -2
  143. package/src/utils/agent-message-runtime/resolveAgentMessageRuntimeActivity.ts +101 -0
  144. package/src/utils/misc/createLazyModuleLoader.ts +27 -0
  145. package/src/version.ts +2 -2
  146. package/src/versions.txt +2 -1
  147. package/umd/index.umd.js +1180 -342
  148. package/umd/index.umd.js.map +1 -1
  149. package/umd/scripts/run-codex-prompts/common/runGoScript/scriptExecutionLog.d.ts +7 -0
  150. package/umd/scripts/run-codex-prompts/git/coderGitSync.d.ts +43 -0
  151. package/umd/scripts/run-codex-prompts/git/commitChanges.d.ts +3 -0
  152. package/umd/scripts/run-codex-prompts/main/resolvePromptRunner.d.ts +8 -1
  153. package/umd/scripts/run-codex-prompts/ping/buildCoderPingPrompt.d.ts +20 -0
  154. package/umd/scripts/run-codex-prompts/ping/extractCoderPingAnswer.d.ts +9 -0
  155. package/umd/scripts/run-codex-prompts/ping/pingCoderHarness.d.ts +23 -0
  156. package/umd/scripts/run-codex-prompts/ping/printCoderPingResult.d.ts +5 -0
  157. package/umd/scripts/run-codex-prompts/prompts/findNextTodoPrompt.d.ts +2 -1
  158. package/umd/scripts/run-codex-prompts/prompts/isPromptCompatibleWithRunner.d.ts +27 -0
  159. package/umd/scripts/run-codex-prompts/prompts/listRunnablePrompts.d.ts +2 -1
  160. package/umd/scripts/run-codex-prompts/prompts/listUpcomingTasks.d.ts +2 -1
  161. package/umd/scripts/run-codex-prompts/prompts/replacePromptTodoStatusLine.d.ts +7 -0
  162. package/umd/scripts/run-codex-prompts/testing/TestBeforeMode.d.ts +16 -0
  163. package/umd/scripts/run-codex-prompts/testing/createTestBeforeRepairPrompt.d.ts +9 -0
  164. package/umd/scripts/run-codex-prompts/testing/limitTestOutput.d.ts +4 -0
  165. package/umd/scripts/run-codex-prompts/testing/runPromptTestCommand.d.ts +1 -2
  166. package/umd/scripts/run-codex-prompts/testing/runTestBefore.d.ts +24 -0
  167. package/umd/scripts/run-codex-prompts/ui/buildRunUiFrameShared.d.ts +1 -0
  168. package/umd/scripts/verify-prompts/verify-prompts.d.ts +5 -0
  169. package/umd/src/book-2.0/book-language-documentation/BookLanguageManualDictionary.d.ts +1 -15
  170. package/umd/src/book-2.0/book-language-documentation/getBookLanguageManualCommitmentGroups.d.ts +1 -1
  171. package/umd/src/book-2.0/book-language-documentation/renderCommitmentCatalogSection.d.ts +0 -4
  172. package/umd/src/book-components/Chat/utils/$provideServerDomWindow.d.ts +11 -0
  173. package/umd/src/book-components/Chat/utils/renderMarkdown.d.ts +7 -0
  174. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/createAgentsServerRuntimeEnvironment.d.ts +7 -0
  175. package/umd/src/cli/cli-commands/coder/agentCodingFile.d.ts +2 -3
  176. package/umd/src/cli/cli-commands/coder/ping.d.ts +10 -0
  177. package/umd/src/cli/cli-commands/coder/ping.test.d.ts +1 -0
  178. package/umd/src/cli/cli-commands/coder.d.ts +1 -0
  179. package/umd/src/cli/cli-commands/common/coderGitSyncCliOptions.d.ts +34 -0
  180. package/umd/src/cli/cli-commands/common/coderGitSyncCliOptions.test.d.ts +1 -0
  181. package/umd/src/cli/common/loadPromptsModule.d.ts +16 -0
  182. package/umd/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.d.ts +1 -1
  183. package/umd/src/llm-providers/azure-openai/AzureOpenAiExecutionTools.d.ts +1 -1
  184. package/umd/src/llm-providers/openai/OpenAiAgentKitExecutionTools.d.ts +1 -1
  185. package/umd/src/llm-providers/openai/OpenAiAgentKitExecutionToolsToolBuilder.d.ts +1 -1
  186. package/umd/src/llm-providers/openai/OpenAiAssistantExecutionToolsStreamRunner.d.ts +1 -1
  187. package/umd/src/llm-providers/openai/OpenAiAssistantExecutionToolsToolRunner.d.ts +1 -1
  188. package/umd/src/llm-providers/openai/OpenAiCompatibleNonChatPromptCaller.d.ts +1 -1
  189. package/umd/src/llm-providers/openai/OpenAiCompatibleRequestManager.d.ts +1 -1
  190. package/umd/src/llm-providers/openai/utils/callOpenAiCompatibleChatModel.d.ts +1 -1
  191. package/umd/src/llm-providers/openai/utils/loadOpenAiAgentsModule.d.ts +203 -0
  192. package/umd/src/llm-providers/openai/utils/uploadFilesToOpenAi.d.ts +1 -1
  193. package/umd/src/utils/misc/createLazyModuleLoader.d.ts +14 -0
  194. package/umd/src/version.d.ts +1 -1
  195. package/apps/agents-server/src/app/api/onboarding/draft/route.ts +0 -23
  196. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/BookLanguagePanel.tsx +0 -125
  197. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/MarkdownBookEditor.tsx +0 -154
  198. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/MarkdownPreview.tsx +0 -188
  199. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/draftService.ts +0 -32
package/README.md CHANGED
@@ -625,26 +625,27 @@ ptbk coder verify
625
625
  | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | ------ | ---- | ----- | ------------------------------------------------------------------------ |
626
626
  | `ptbk coder init` | Creates `prompts/`, `prompts/done/`, the project-generic template files materialized in `prompts/templates/` (currently `common.md`), and a starter `AGENTS.md`; ensures `.env` contains `CODING_AGENT_GIT_NAME`, `CODING_AGENT_GIT_EMAIL`, and `CODING_AGENT_GIT_SIGNING_KEY`; adds helper coder scripts to `package.json`; ensures `.gitignore` contains `/.promptbook`; and configures `.vscode/settings.json` to save pasted prompt images into `prompts/screenshots/`. |
627
627
  | `ptbk coder generate-boilerplates` | Creates new prompt markdown files with fresh emoji tags so you can quickly fill in coding tasks; `--template` accepts either a built-in alias or a markdown file path relative to the project root. |
628
- | `ptbk coder run` | Picks the next ready prompt, appends optional context, runs it through the selected coding agent, can optionally verify each attempt with a shell test command and feed failing output back for retries, then marks success or failure, commits the result, and pushes only when `--auto-push` is enabled. |
628
+ | `ptbk coder run` | Picks the next ready prompt, can run tests before coding to stop or repair pre-existing failures, appends optional context, runs it through the selected coding agent, can optionally verify each attempt with a shell test command and feed failing output back for retries, then marks success or failure, commits the result, and pushes only when `--auto-push` is enabled. |
629
629
  | `ptbk coder find-refactor-candidates` | Scans the repository for oversized or overpacked files and writes prompt files for likely refactors; `--level <xlow | low | medium | high | xhigh | extreme>` ranges from a very benevolent scan to a very aggressive sweep. |
630
630
  | `ptbk coder verify` | Walks through completed prompts, archives truly finished work, and adds follow-up repair prompts for unfinished results. |
631
631
 
632
632
  #### Most useful `ptbk coder run` flags
633
633
 
634
- | Flag | Purpose |
635
- | -------------------------- | -------------------------------------------------------------------------------------------------- |
636
- | `--harness <name>` | Selects the coding harness. |
637
- | `--model <model>` | Chooses the runner model; required for `openai-codex` and `gemini`, optional for `github-copilot`. |
638
- | `--context <text-or-file>` | Appends extra instructions inline or from a file like `AGENTS.md`. |
639
- | `--test <command>` | Runs a verification command after each prompt attempt and feeds failing output back for retries. |
640
- | `--thinking-level <level>` | Sets reasoning effort for supported runners. |
641
- | `--no-auto` | Waits for user confirmation before each prompt instead of running automatically through the queue. |
642
- | `--ignore-git-changes` | Disables the clean-working-tree guard. |
643
- | `--priority <n>` | Runs only prompts at or above the given priority. |
644
- | `--dry-run` | Prints which prompts are ready instead of executing them. |
645
- | `--allow-credits` | Lets OpenAI Codex spend credits when required. |
646
- | `--auto-push` | Pushes each successful coding-agent commit to the configured remote. |
647
- | `--auto-migrate` | Runs testing-server database migrations after each successful prompt. |
634
+ | Flag | Purpose |
635
+ | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
636
+ | `--harness <name>` | Selects the coding harness. |
637
+ | `--model <model>` | Chooses the runner model; required for `openai-codex` and `gemini`, optional for `github-copilot`. |
638
+ | `--context <text-or-file>` | Appends extra instructions inline or from a file like `AGENTS.md`. |
639
+ | `--test <command>` | Runs a verification command after each prompt attempt and feeds failing output back for retries. |
640
+ | `--test-before <mode>` | Runs tests before coding: `no` (default), `yes-and-fail` (stop with results), or `yes-and-fix` (create one repair prompt first); defaults to `npm test` when enabled without `--test`. |
641
+ | `--thinking-level <level>` | Sets reasoning effort for supported runners. |
642
+ | `--no-auto` | Waits for user confirmation before each prompt instead of running automatically through the queue. |
643
+ | `--ignore-git-changes` | Disables the clean-working-tree guard. |
644
+ | `--priority <n>` | Runs only prompts at or above the given priority. |
645
+ | `--dry-run` | Prints which prompts are ready instead of executing them. |
646
+ | `--allow-credits` | Lets OpenAI Codex spend credits when required. |
647
+ | `--auto-push` | Pushes each successful coding-agent commit to the configured remote. |
648
+ | `--auto-migrate` | Runs testing-server database migrations after each successful prompt. |
648
649
 
649
650
  #### Typical usage pattern
650
651
 
@@ -22,6 +22,11 @@ const agentsServerNodeModulesPath = process.env.PTBK_AGENTS_SERVER_NODE_MODULES_
22
22
  */
23
23
  const isNextValidationIgnored = process.env.PTBK_AGENTS_SERVER_IGNORE_NEXT_VALIDATION === 'true';
24
24
 
25
+ /**
26
+ * Whether one isolated CLI production build should avoid writing a webpack filesystem cache that no later release can reuse.
27
+ */
28
+ const isWebpackFilesystemCacheDisabled = process.env.PTBK_AGENTS_SERVER_DISABLE_WEBPACK_FILESYSTEM_CACHE === 'true';
29
+
25
30
  /**
26
31
  * Optional worker count override for CLI-owned production builds on memory-constrained VPS hosts.
27
32
  */
@@ -79,6 +84,12 @@ const nextConfig: NextConfig = {
79
84
  },
80
85
 
81
86
  webpack(config, { isServer, nextRuntime }) {
87
+ if (isWebpackFilesystemCacheDisabled) {
88
+ // Versioned VPS releases build into a fresh checkout. Persisting the multi-gigabyte webpack cache there
89
+ // adds substantial disk I/O but cannot accelerate the next release, which has a different checkout.
90
+ config.cache = false;
91
+ }
92
+
82
93
  config.resolve.alias = {
83
94
  ...config.resolve.alias,
84
95
  '@': path.resolve(__dirname),
@@ -5,13 +5,15 @@
5
5
  "prebuild": "npm run generate-reserved-paths && node ./scripts/clearNextGeneratedTypes.js && npx kill-port 4440 || exit 0",
6
6
  "predev": "npm run generate-reserved-paths && npx kill-port 4440 || exit 0",
7
7
  "dev": "next dev -p 4440",
8
- "test": "npm run lint && npm run test-build && npm run test-e2e",
9
- "test-e2e": "playwright test",
8
+ "test": "npm run test-e2e",
9
+ "test-e2e": "node ./scripts/run-e2e-tests.js",
10
10
  "pretest-build": "npx kill-port 4021 4440 || exit 0",
11
11
  "test-build": "npm run build",
12
- "build": "node --max-old-space-size=8192 -r ./scripts/ignore-kill-eperm.js ./scripts/next-cli.js build && node ./scripts/prerender-homepage.js",
12
+ "pretest-e2e": "npx kill-port 4021 4440 || exit 0",
13
+ "build": "node ./scripts/build-agents-server.js",
14
+ "build-e2e": "node ./scripts/build-e2e.js",
13
15
  "start": "next start -p 4440",
14
16
  "lint": "eslint src/ --max-warnings=0",
15
- "postinstall": "cd ../../ && npm ci"
17
+ "postinstall": "node ./scripts/ensure-root-dependencies.js"
16
18
  }
17
19
  }
@@ -2,54 +2,45 @@ import path from 'path';
2
2
  import { defineConfig, devices } from 'playwright/test';
3
3
 
4
4
  /**
5
- * Local host and port used by the mocked Supabase API during integration tests.
5
+ * Shape of the shared CommonJS module used by the E2E build, server, and Playwright configuration.
6
6
  */
7
- const MOCK_SUPABASE_PORT = 54321;
8
-
9
- /**
10
- * Base URL served by the mocked Supabase API.
11
- */
12
- const MOCK_SUPABASE_URL = `http://127.0.0.1:${MOCK_SUPABASE_PORT}`;
7
+ type E2eEnvironmentModule = {
8
+ readonly APP_E2E_ENV: Readonly<Record<string, string>>;
9
+ readonly APP_PORT: number;
10
+ readonly APP_URL: string;
11
+ readonly MOCK_SUPABASE_PORT: number;
12
+ readonly MOCK_SUPABASE_URL: string;
13
+ };
13
14
 
14
- /**
15
- * Local host and port used by the Agents Server application during integration tests.
16
- */
17
- const APP_PORT = 4440;
15
+ const {
16
+ APP_E2E_ENV,
17
+ APP_PORT,
18
+ APP_URL,
19
+ MOCK_SUPABASE_PORT,
20
+ MOCK_SUPABASE_URL,
21
+ } = require('./tests/e2e/e2eEnvironment.cjs') as E2eEnvironmentModule;
18
22
 
19
23
  /**
20
- * Base URL served by the Agents Server application during integration tests.
24
+ * Maximum time allowed for the production Agents Server bundle used by browser tests.
21
25
  */
22
- const APP_URL = `http://127.0.0.1:${APP_PORT}`;
26
+ const E2E_WEB_SERVER_TIMEOUT_MS = 30 * 60 * 1000;
23
27
 
24
28
  /**
25
- * Maximum time allowed for the production Agents Server bundle used by browser tests.
29
+ * Directory under the repository root that should hold Playwright artifacts such as recorded videos.
26
30
  */
27
- const E2E_WEB_SERVER_TIMEOUT_MS = 30 * 60 * 1000;
31
+ const E2E_ARTIFACTS_DIR = path.join(__dirname, '..', '..', 'other', 'integration-tests', 'videos');
28
32
 
29
33
  /**
30
- * Shared environment variables required by the Agents Server in deterministic e2e runs.
34
+ * Uses the already prepared production build when the test runner created it.
35
+ * Direct Playwright invocations keep the self-bootstrapping build behavior.
31
36
  */
32
- const APP_E2E_ENV = {
33
- ADMIN_PASSWORD: 'e2e-admin-password',
34
- SESSION_SECRET: 'e2e-session-secret-must-differ-from-admin-password',
35
- PTBK_AGENTS_SERVER_USER_CHAT_WORKER_TOKEN: 'e2e-user-chat-worker-token-must-differ-from-admin-password',
36
- PROMPTBOOK_TEAM_AGENT_ACCESS_TOKEN: 'e2e-team-agent-access-token-must-differ-from-admin-password',
37
- NEXT_DIST_DIR: '.next-e2e',
38
- NEXT_PUBLIC_SITE_URL: APP_URL,
39
- PTBK_AGENTS_SERVER_DATABASE: 'supabase',
40
- PTBK_AGENTS_SERVER_SQLITE_PATH: '',
41
- SUPABASE_TABLE_PREFIX: '',
42
- POSTGRES_URL: '',
43
- DATABASE_URL: '',
44
- NEXT_PUBLIC_SUPABASE_URL: MOCK_SUPABASE_URL,
45
- NEXT_PUBLIC_SUPABASE_ANON_KEY: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiJ9.e2e-signature',
46
- SUPABASE_SERVICE_ROLE_KEY: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIn0.e2e-signature',
47
- };
37
+ const E2E_APP_WEB_SERVER_COMMAND =
38
+ process.env.PTBK_E2E_BUILD_READY === 'true' ? 'npm run start' : 'node ./scripts/build-e2e.js --start';
48
39
 
49
40
  /**
50
- * Directory under the repository root that should hold Playwright artifacts such as recorded videos.
41
+ * Environment inherited by the local E2E web servers.
51
42
  */
52
- const E2E_ARTIFACTS_DIR = path.join(__dirname, '..', '..', 'other', 'integration-tests', 'videos');
43
+ const PROCESS_ENVIRONMENT = process.env as Record<string, string>;
53
44
 
54
45
  /**
55
46
  * Playwright configuration for Agents Server integration tests.
@@ -88,7 +79,7 @@ const config = defineConfig({
88
79
  stdout: 'pipe',
89
80
  stderr: 'pipe',
90
81
  env: {
91
- ...process.env,
82
+ ...PROCESS_ENVIRONMENT,
92
83
  E2E_SUPABASE_PORT: String(MOCK_SUPABASE_PORT),
93
84
  E2E_SERVER_NAME: 'local-e2e',
94
85
  E2E_SERVER_ENVIRONMENT: 'PREVIEW',
@@ -97,8 +88,7 @@ const config = defineConfig({
97
88
  },
98
89
  },
99
90
  {
100
- command:
101
- 'npm run prebuild && node --max-old-space-size=8192 -r ./scripts/ignore-kill-eperm.js ./scripts/next-cli.js build && npm run start',
91
+ command: E2E_APP_WEB_SERVER_COMMAND,
102
92
  cwd: __dirname,
103
93
  url: APP_URL,
104
94
  reuseExistingServer: false,
@@ -106,7 +96,7 @@ const config = defineConfig({
106
96
  stdout: 'pipe',
107
97
  stderr: 'pipe',
108
98
  env: {
109
- ...process.env,
99
+ ...PROCESS_ENVIRONMENT,
110
100
  ...APP_E2E_ENV,
111
101
  },
112
102
  },
@@ -0,0 +1,62 @@
1
+ 'use strict';
2
+
3
+ const { spawnSync } = require('node:child_process');
4
+ const path = require('node:path');
5
+
6
+ /**
7
+ * Root directory of the Agents Server app.
8
+ */
9
+ const APP_ROOT = path.resolve(__dirname, '..');
10
+
11
+ /**
12
+ * Maximum Node.js heap size used by the Next.js production build.
13
+ */
14
+ const AGENTS_SERVER_BUILD_MAX_OLD_SPACE_MIB = 8192;
15
+
16
+ /**
17
+ * Runs the shared Agents Server production build and its homepage prerender step.
18
+ *
19
+ * The optional `--no-lint` argument is used by the E2E runner after the same app
20
+ * lint command has already completed successfully.
21
+ */
22
+ function buildAgentsServer() {
23
+ const nextBuildArguments = [
24
+ `--max-old-space-size=${AGENTS_SERVER_BUILD_MAX_OLD_SPACE_MIB}`,
25
+ '-r',
26
+ path.join(APP_ROOT, 'scripts', 'ignore-kill-eperm.js'),
27
+ path.join(APP_ROOT, 'scripts', 'next-cli.js'),
28
+ 'build',
29
+ ];
30
+
31
+ if (process.argv.includes('--no-lint')) {
32
+ nextBuildArguments.push('--no-lint');
33
+ }
34
+
35
+ runChildProcess(process.execPath, nextBuildArguments);
36
+ runChildProcess(process.execPath, [path.join(APP_ROOT, 'scripts', 'prerender-homepage.js')]);
37
+ }
38
+
39
+ /**
40
+ * Runs one child process and forwards its exit status.
41
+ *
42
+ * @param executablePath - Executable to run.
43
+ * @param argumentsList - Arguments passed to the executable.
44
+ */
45
+ function runChildProcess(executablePath, argumentsList) {
46
+ const result = spawnSync(executablePath, argumentsList, {
47
+ cwd: APP_ROOT,
48
+ env: process.env,
49
+ stdio: 'inherit',
50
+ });
51
+
52
+ if (result.error) {
53
+ console.error(`Failed to run ${executablePath}:`, result.error);
54
+ process.exit(1);
55
+ }
56
+
57
+ if (result.status !== 0) {
58
+ process.exit(result.status ?? 1);
59
+ }
60
+ }
61
+
62
+ buildAgentsServer();
@@ -0,0 +1,38 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const { APP_E2E_ENV } = require('../tests/e2e/e2eEnvironment.cjs');
5
+ const { runNpm } = require('./run-npm.js');
6
+
7
+ /**
8
+ * Root directory of the Agents Server app.
9
+ */
10
+ const APP_ROOT = path.resolve(__dirname, '..');
11
+
12
+ /**
13
+ * Builds the production bundle used by the Agents Server E2E tests.
14
+ *
15
+ * The E2E environment is applied while compiling so public values such as the
16
+ * mocked Supabase URL are embedded consistently in browser bundles.
17
+ */
18
+ function buildE2eServer() {
19
+ const buildArguments = ['run', 'build'];
20
+
21
+ if (process.argv.includes('--no-lint')) {
22
+ buildArguments.push('--', '--no-lint');
23
+ }
24
+
25
+ runNpm(buildArguments, {
26
+ cwd: APP_ROOT,
27
+ environmentOverrides: APP_E2E_ENV,
28
+ });
29
+
30
+ if (process.argv.includes('--start')) {
31
+ runNpm(['run', 'start'], {
32
+ cwd: APP_ROOT,
33
+ environmentOverrides: APP_E2E_ENV,
34
+ });
35
+ }
36
+ }
37
+
38
+ buildE2eServer();
@@ -0,0 +1,86 @@
1
+ 'use strict';
2
+
3
+ const { createHash } = require('node:crypto');
4
+ const { createRequire } = require('node:module');
5
+ const { existsSync, readFileSync, writeFileSync } = require('node:fs');
6
+ const path = require('node:path');
7
+ const { runNpm } = require('./run-npm.js');
8
+
9
+ /**
10
+ * Root directory whose dependency tree is used by the Agents Server app.
11
+ */
12
+ const REPOSITORY_ROOT = path.resolve(__dirname, '..', '..');
13
+
14
+ /**
15
+ * Root package lock file used to validate the installed dependency tree.
16
+ */
17
+ const PACKAGE_LOCK_FILE_PATH = path.join(REPOSITORY_ROOT, 'package-lock.json');
18
+
19
+ /**
20
+ * Marker persisted inside `node_modules` after a successful root dependency installation.
21
+ */
22
+ const ROOT_DEPENDENCY_MARKER_PATH = path.join(
23
+ REPOSITORY_ROOT,
24
+ 'node_modules',
25
+ '.promptbook-package-lock-hash',
26
+ );
27
+
28
+ /**
29
+ * Small set of packages required to recognize a usable root dependency tree.
30
+ */
31
+ const REQUIRED_ROOT_PACKAGE_NAMES = ['next', 'typescript', 'ts-node', '@playwright/test'];
32
+
33
+ /**
34
+ * Ensures that installing the nested app does not reinstall the root dependency tree on every run.
35
+ */
36
+ function ensureRootDependencies() {
37
+ const packageLockHash = createPackageLockHash();
38
+
39
+ if (isRootDependencyTreeCurrent(packageLockHash)) {
40
+ return;
41
+ }
42
+
43
+ runNpm(['ci', '--include=dev', '--prefer-offline', '--no-audit', '--no-fund'], {
44
+ cwd: REPOSITORY_ROOT,
45
+ });
46
+
47
+ writeFileSync(ROOT_DEPENDENCY_MARKER_PATH, `${packageLockHash}\n`, 'utf8');
48
+ }
49
+
50
+ /**
51
+ * Creates a stable hash for the root package lock file.
52
+ *
53
+ * @returns SHA-256 hash of the package lock contents.
54
+ */
55
+ function createPackageLockHash() {
56
+ return createHash('sha256').update(readFileSync(PACKAGE_LOCK_FILE_PATH)).digest('hex');
57
+ }
58
+
59
+ /**
60
+ * Checks whether the root dependency tree matches the current package lock file.
61
+ *
62
+ * @param packageLockHash - Expected package lock hash.
63
+ * @returns Whether the existing root dependency tree can be reused.
64
+ */
65
+ function isRootDependencyTreeCurrent(packageLockHash) {
66
+ if (!existsSync(ROOT_DEPENDENCY_MARKER_PATH)) {
67
+ return false;
68
+ }
69
+
70
+ if (readFileSync(ROOT_DEPENDENCY_MARKER_PATH, 'utf8').trim() !== packageLockHash) {
71
+ return false;
72
+ }
73
+
74
+ const rootRequire = createRequire(path.join(REPOSITORY_ROOT, 'package.json'));
75
+
76
+ return REQUIRED_ROOT_PACKAGE_NAMES.every((packageName) => {
77
+ try {
78
+ rootRequire.resolve(`${packageName}/package.json`);
79
+ return true;
80
+ } catch {
81
+ return false;
82
+ }
83
+ });
84
+ }
85
+
86
+ ensureRootDependencies();
@@ -32,7 +32,7 @@ const SERVER_READY_MARKER = 'Ready in';
32
32
  /**
33
33
  * Constant for output dir.
34
34
  */
35
- const OUTPUT_DIR = path.join(APP_ROOT, '.next', 'prerendered');
35
+ const OUTPUT_DIR = path.join(APP_ROOT, process.env.NEXT_DIST_DIR || '.next', 'prerendered');
36
36
  /**
37
37
  * Constant for output file.
38
38
  */
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const { runNpm } = require('./run-npm.js');
5
+
6
+ /**
7
+ * Root directory of the Agents Server app.
8
+ */
9
+ const APP_ROOT = path.resolve(__dirname, '..');
10
+
11
+ /**
12
+ * Runs the complete Agents Server E2E verification flow.
13
+ *
14
+ * App linting remains an explicit test phase. The production build then skips
15
+ * its duplicate lint pass, and Playwright starts that same build instead of
16
+ * compiling a second `.next-e2e` output through `webServer`.
17
+ */
18
+ function runE2eTests() {
19
+ const commandOptions = {
20
+ cwd: APP_ROOT,
21
+ };
22
+
23
+ runNpm(['run', 'lint'], commandOptions);
24
+ runNpm(['run', 'build-e2e', '--', '--no-lint'], commandOptions);
25
+
26
+ runNpm(['exec', '--', 'playwright', 'test', ...process.argv.slice(2)], {
27
+ ...commandOptions,
28
+ environmentOverrides: {
29
+ PTBK_E2E_BUILD_READY: 'true',
30
+ },
31
+ });
32
+ }
33
+
34
+ runE2eTests();
@@ -0,0 +1,42 @@
1
+ 'use strict';
2
+
3
+ const { spawnSync } = require('node:child_process');
4
+
5
+ /**
6
+ * Platform-specific npm executable.
7
+ */
8
+ const NPM_EXECUTABLE = process.platform === 'win32' ? 'npm.cmd' : 'npm';
9
+
10
+ /**
11
+ * Runs one npm command and forwards its output and exit status.
12
+ *
13
+ * Windows resolves npm through a `.cmd` shim, which needs shell execution when spawned from
14
+ * Node.js on some supported Node versions.
15
+ *
16
+ * @param {ReadonlyArray<string>} argumentsList - Arguments passed to npm.
17
+ * @param {{ cwd: string, environmentOverrides?: Readonly<Record<string, string>> }} options - Command options.
18
+ */
19
+ function runNpm(argumentsList, { cwd, environmentOverrides = {} }) {
20
+ const result = spawnSync(NPM_EXECUTABLE, argumentsList, {
21
+ cwd,
22
+ env: {
23
+ ...process.env,
24
+ ...environmentOverrides,
25
+ },
26
+ shell: process.platform === 'win32',
27
+ stdio: 'inherit',
28
+ });
29
+
30
+ if (result.error) {
31
+ console.error(`Failed to run ${NPM_EXECUTABLE}:`, result.error);
32
+ process.exit(1);
33
+ }
34
+
35
+ if (result.status !== 0) {
36
+ process.exit(result.status ?? 1);
37
+ }
38
+ }
39
+
40
+ module.exports = {
41
+ runNpm,
42
+ };
@@ -27,7 +27,7 @@ export default async function AdminEmailServerPage() {
27
27
 
28
28
  const server = await $provideServer();
29
29
  const snapshot = await readStalwartEmailSnapshot(server.publicUrl.hostname);
30
- const dnsInstructions = createEmailDnsInstructions(snapshot.domain);
30
+ const dnsInstructions = createEmailDnsInstructions(snapshot.domain, snapshot.mailDnsDiagnostic.publicIpAddress);
31
31
  const isOperational = isStalwartEmailSnapshotOperational(snapshot);
32
32
 
33
33
  return (
@@ -55,7 +55,8 @@ export default async function AdminEmailServerPage() {
55
55
  Domain <code>{snapshot.domain}</code> · API{' '}
56
56
  {snapshot.isReachable ? 'reachable' : 'unavailable'} · bridge{' '}
57
57
  {snapshot.isBridgeAccountConfigured ? 'configured' : 'missing'} · inbound hook{' '}
58
- {snapshot.isInboundHookConfigured ? 'configured' : 'missing'}
58
+ {snapshot.isInboundHookConfigured ? 'configured' : 'missing'} · public mail DNS{' '}
59
+ {snapshot.mailDnsDiagnostic.status === 'verified' ? 'verified' : 'needs attention'}
59
60
  </p>
60
61
  {snapshot.errorMessage ? (
61
62
  <p className="mt-2 max-w-4xl whitespace-pre-wrap text-xs">
@@ -110,10 +111,17 @@ export default async function AdminEmailServerPage() {
110
111
  <div className="mt-4">
111
112
  <DnsRecordsInstructions
112
113
  description={
113
- <p>
114
- Add these records at your DNS provider. Replace <code>&lt;VPS_PUBLIC_IP&gt;</code>{' '}
115
- with the public address of this VPS.
116
- </p>
114
+ snapshot.mailDnsDiagnostic.publicIpAddress ? (
115
+ <p>
116
+ Add these records at your DNS provider. The A records below use this VPS’s
117
+ detected public address.
118
+ </p>
119
+ ) : (
120
+ <p>
121
+ Add these records at your DNS provider. Replace <code>&lt;VPS_PUBLIC_IP&gt;</code>{' '}
122
+ with the public address of this VPS.
123
+ </p>
124
+ )
117
125
  }
118
126
  domain={snapshot.domain}
119
127
  recordSelection="all"
@@ -31,7 +31,7 @@ const ELEVEN_LABS_MODEL_ID = process.env.ELEVEN_LABS_MODEL_ID ?? 'eleven_multili
31
31
  *
32
32
  * @private
33
33
  */
34
- const ELEVEN_LABS_API_KEY = process.env.ELEVEN_LABS_API_KEY;
34
+ const ELEVENLABS_API_KEY = process.env.ELEVENLABS_API_KEY;
35
35
 
36
36
  /**
37
37
  * Maximum number of characters that are sent to a single ElevenLabs TTS request.
@@ -89,7 +89,7 @@ export async function POST(request: NextRequest) {
89
89
  });
90
90
  }
91
91
 
92
- if (!ELEVEN_LABS_API_KEY) {
92
+ if (!ELEVENLABS_API_KEY) {
93
93
  return new Response(
94
94
  JSON.stringify({
95
95
  error: 'ElevenLabs API key is not configured on the server.',
@@ -153,7 +153,7 @@ export async function POST(request: NextRequest) {
153
153
  method: 'POST',
154
154
  headers: {
155
155
  'Content-Type': 'application/json',
156
- 'xi-api-key': ELEVEN_LABS_API_KEY,
156
+ 'xi-api-key': ELEVENLABS_API_KEY,
157
157
  },
158
158
  body: JSON.stringify({
159
159
  text: limitedText,
@@ -1,21 +1,22 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
- import { convertManGoDraftToBook } from '@/src/utils/manGoOnboarding/manGoOnboardingAgentRuntime';
2
+ import { generateManGoBook } from '@/src/utils/manGoOnboarding/manGoOnboardingAgentRuntime';
3
3
  import { createManGoOnboardingApiErrorResponse } from '@/src/utils/manGoOnboarding/manGoOnboardingApiResponses';
4
4
  import { readManGoOnboardingStringProperty } from '@/src/utils/manGoOnboarding/manGoOnboardingApiRequest';
5
5
 
6
6
  /**
7
7
  * Handles `POST /api/onboarding/book`.
8
8
  *
9
- * @param request - Incoming request with the editable draft input.
10
- * @returns Canonical Book-language source and validation flag.
9
+ * @param request - Incoming request with `agentName` and `agentBrief`.
10
+ * @returns Generated Book-language source.
11
11
  */
12
12
  export async function POST(request: NextRequest) {
13
13
  try {
14
14
  const body = await request.json();
15
- const input = readManGoOnboardingStringProperty(body, 'input');
16
- const result = await convertManGoDraftToBook({ input });
15
+ const agentName = readManGoOnboardingStringProperty(body, 'agentName');
16
+ const agentBrief = readManGoOnboardingStringProperty(body, 'agentBrief');
17
+ const book = await generateManGoBook({ agentName, agentBrief });
17
18
 
18
- return NextResponse.json(result);
19
+ return NextResponse.json({ book });
19
20
  } catch (error) {
20
21
  return createManGoOnboardingApiErrorResponse(error);
21
22
  }
@@ -4,6 +4,7 @@ import { createThemeModeBootstrapScript } from '@/src/components/ThemeMode/creat
4
4
  import { APPLICATION_FONT_VARIABLE_CLASS_NAME } from '@/src/utils/applicationFonts';
5
5
  import type { Metadata } from 'next';
6
6
  import { cookies, headers } from 'next/headers';
7
+ import { connection } from 'next/server';
7
8
  import { CONTENT_SECURITY_POLICY_NONCE_REQUEST_HEADER } from '../middleware/contentSecurityPolicy';
8
9
  import { getCustomJavascriptWithIntegrations } from '../database/customJavascript';
9
10
  import { getAggregatedCustomStylesheetCss } from '../database/customStylesheet';
@@ -349,6 +350,11 @@ export default async function RootLayout({
349
350
  }: Readonly<{
350
351
  children: React.ReactNode;
351
352
  }>) {
353
+ // Every page uses this request-aware layout (cookies, headers, and the current user). Tell Next.js before
354
+ // starting its database-backed work so a production build does not repeat that work for every static-render
355
+ // attempt only to discover that the route must be dynamic.
356
+ await connection();
357
+
352
358
  const layoutMetadataPromise = getMetadataMap([
353
359
  'SERVER_NAME',
354
360
  'SERVER_LOGO_URL',