@promptbook/cli 0.112.0-96 → 0.112.0-98

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 (79) hide show
  1. package/apps/agents-server/playwright.config.ts +2 -1
  2. package/apps/agents-server/src/app/admin/cli-access/CliAccessClient.tsx +99 -0
  3. package/apps/agents-server/src/app/admin/cli-access/page.tsx +14 -0
  4. package/apps/agents-server/src/app/admin/code-runners/CodeRunnersClient.tsx +124 -34
  5. package/apps/agents-server/src/app/admin/servers/CreateServerDialog.tsx +46 -505
  6. package/apps/agents-server/src/app/admin/servers/ServersClient.tsx +23 -11
  7. package/apps/agents-server/src/app/admin/servers/ServersRegistryApi.ts +5 -0
  8. package/apps/agents-server/src/app/admin/servers/ServersRegistryDnsTypes.ts +87 -0
  9. package/apps/agents-server/src/app/admin/servers/ServersRegistryTable.tsx +258 -128
  10. package/apps/agents-server/src/app/admin/servers/useCreateServerWizard.ts +46 -334
  11. package/apps/agents-server/src/app/admin/servers/useServersRegistryState.ts +26 -2
  12. package/apps/agents-server/src/app/admin/update/UpdateClient.tsx +435 -0
  13. package/apps/agents-server/src/app/admin/update/page.tsx +14 -0
  14. package/apps/agents-server/src/app/agents/[agentName]/chat/CanonicalAgentChatSurface.tsx +24 -0
  15. package/apps/agents-server/src/app/api/admin/cli-access/route.ts +137 -0
  16. package/apps/agents-server/src/app/api/admin/code-runners/authentication/route.ts +140 -0
  17. package/apps/agents-server/src/app/api/admin/code-runners/route.ts +4 -35
  18. package/apps/agents-server/src/app/api/admin/servers/[serverId]/route.ts +7 -2
  19. package/apps/agents-server/src/app/api/admin/servers/route.ts +95 -4
  20. package/apps/agents-server/src/app/api/admin/update/route.ts +52 -0
  21. package/apps/agents-server/src/app/api/auth/login/route.ts +8 -0
  22. package/apps/agents-server/src/app/api/auth/logout/route.ts +10 -2
  23. package/apps/agents-server/src/app/api/chat/export/pdf/route.ts +63 -0
  24. package/apps/agents-server/src/app/page.tsx +10 -0
  25. package/apps/agents-server/src/components/AdminTerminal/AdminTerminalCard.tsx +279 -0
  26. package/apps/agents-server/src/components/AdminTerminal/useAdminTerminalSession.ts +336 -0
  27. package/apps/agents-server/src/components/Header/buildHeaderSystemMenuItems.ts +10 -0
  28. package/apps/agents-server/src/languages/ServerTranslationKeys.ts +2 -0
  29. package/apps/agents-server/src/languages/translations/czech.yaml +2 -0
  30. package/apps/agents-server/src/languages/translations/english.yaml +2 -0
  31. package/apps/agents-server/src/middleware.ts +32 -0
  32. package/apps/agents-server/src/tools/BrowserConnectionProvider.ts +1 -1
  33. package/apps/agents-server/src/utils/chatExport/downloadChatPdfFromServer.ts +59 -0
  34. package/apps/agents-server/src/utils/chatExport/renderHtmlToPdfOnServer.ts +37 -0
  35. package/apps/agents-server/src/utils/codeRunnerAuthentication.ts +234 -0
  36. package/apps/agents-server/src/utils/codeRunnerConfiguration.ts +67 -0
  37. package/apps/agents-server/src/utils/createInteractiveTerminalEventStream.ts +84 -0
  38. package/apps/agents-server/src/utils/interactiveTerminalSession.ts +442 -0
  39. package/apps/agents-server/src/utils/serverCliAccess.ts +221 -0
  40. package/apps/agents-server/src/utils/serverManagement/standaloneVpsServerMetadata.ts +145 -0
  41. package/apps/agents-server/src/utils/serverRegistry.ts +3 -2
  42. package/apps/agents-server/src/utils/session.ts +37 -9
  43. package/apps/agents-server/src/utils/shibboleth/createShibbolethAuthenticationLogPayload.ts +173 -0
  44. package/apps/agents-server/src/utils/shibboleth/writeShibbolethAuthenticationLog.ts +27 -0
  45. package/apps/agents-server/src/utils/standaloneVpsDnsDiagnostics.ts +258 -0
  46. package/apps/agents-server/src/utils/standaloneVpsRawIpBootstrap.ts +87 -0
  47. package/apps/agents-server/src/utils/vpsConfiguration.ts +87 -13
  48. package/apps/agents-server/src/utils/vpsSelfUpdate.ts +664 -0
  49. package/esm/apps/agents-server/src/utils/serverRegistry.d.ts +1 -1
  50. package/esm/index.es.js +7 -5
  51. package/esm/index.es.js.map +1 -1
  52. package/esm/src/book-components/Chat/Chat/ChatActionsBar.d.ts +2 -0
  53. package/esm/src/book-components/Chat/Chat/ChatProps.d.ts +6 -0
  54. package/esm/src/book-components/Chat/save/_common/ChatSaveFormatHandler.d.ts +35 -0
  55. package/esm/src/book-components/Chat/save/_common/createChatExportFilename.d.ts +11 -0
  56. package/esm/src/version.d.ts +1 -1
  57. package/package.json +1 -1
  58. package/src/book-components/Chat/Chat/Chat.tsx +2 -0
  59. package/src/book-components/Chat/Chat/ChatActionsBar.tsx +17 -9
  60. package/src/book-components/Chat/Chat/ChatProps.tsx +7 -0
  61. package/src/book-components/Chat/save/_common/ChatSaveFormatHandler.ts +40 -0
  62. package/src/book-components/Chat/save/_common/createChatExportFilename.ts +20 -0
  63. package/src/book-components/Chat/utils/renderMarkdown.ts +1 -3
  64. package/src/other/templates/getTemplatesPipelineCollection.ts +718 -790
  65. package/src/scrapers/document/DocumentScraper.ts +1 -1
  66. package/src/scrapers/document-legacy/LegacyDocumentScraper.ts +1 -1
  67. package/src/version.ts +2 -2
  68. package/src/versions.txt +2 -0
  69. package/umd/apps/agents-server/src/utils/serverRegistry.d.ts +1 -1
  70. package/umd/index.umd.js +7 -5
  71. package/umd/index.umd.js.map +1 -1
  72. package/umd/src/book-components/Chat/Chat/ChatActionsBar.d.ts +2 -0
  73. package/umd/src/book-components/Chat/Chat/ChatProps.d.ts +6 -0
  74. package/umd/src/book-components/Chat/save/_common/ChatSaveFormatHandler.d.ts +35 -0
  75. package/umd/src/book-components/Chat/save/_common/createChatExportFilename.d.ts +11 -0
  76. package/umd/src/version.d.ts +1 -1
  77. package/src/conversion/validation/_importPipeline.ts +0 -88
  78. /package/esm/src/conversion/validation/{_importPipeline.d.ts → _importPipeline.test.d.ts} +0 -0
  79. /package/umd/src/conversion/validation/{_importPipeline.d.ts → _importPipeline.test.d.ts} +0 -0
@@ -88,7 +88,7 @@ export type CreateServerWizardState = {
88
88
  name: string;
89
89
 
90
90
  /**
91
- * Safe slug used to derive the table prefix.
91
+ * Safe slug derived from the server name.
92
92
  */
93
93
  identifier: string;
94
94
 
@@ -108,7 +108,7 @@ export type CreateServerWizardState = {
108
108
  iconUrl: string;
109
109
 
110
110
  /**
111
- * Mandatory first admin account.
111
+ * Installer-managed admin account.
112
112
  */
113
113
  adminUser: {
114
114
  username: string;
@@ -154,103 +154,12 @@ export type CreateServerWizardError = {
154
154
  * @private function of <ServersClient/>
155
155
  */
156
156
  export type UpdateCreateServerWizardField = <
157
- TFieldName extends keyof Pick<
158
- CreateServerWizardState,
159
- 'name' | 'identifier' | 'environment' | 'domain' | 'iconUrl'
160
- >,
157
+ TFieldName extends keyof Pick<CreateServerWizardState, 'name' | 'domain' | 'iconUrl'>,
161
158
  >(
162
159
  fieldName: TFieldName,
163
160
  value: CreateServerWizardState[TFieldName],
164
161
  ) => void;
165
162
 
166
- /**
167
- * Admin-user updater shared with the dialog component.
168
- *
169
- * @private function of <ServersClient/>
170
- */
171
- export type UpdateCreateServerAdminField = <TFieldName extends keyof CreateServerWizardState['adminUser']>(
172
- fieldName: TFieldName,
173
- value: CreateServerWizardState['adminUser'][TFieldName],
174
- ) => void;
175
-
176
- /**
177
- * Initial-settings updater shared with the dialog component.
178
- *
179
- * @private function of <ServersClient/>
180
- */
181
- export type UpdateCreateServerInitialSetting = <TFieldName extends keyof CreateServerWizardState['initialSettings']>(
182
- fieldName: TFieldName,
183
- value: CreateServerWizardState['initialSettings'][TFieldName],
184
- ) => void;
185
-
186
- /**
187
- * Additional-user updater shared with the dialog component.
188
- *
189
- * @private function of <ServersClient/>
190
- */
191
- export type UpdateCreateServerAdditionalUser = <TFieldName extends keyof WizardUser>(
192
- index: number,
193
- fieldName: TFieldName,
194
- value: WizardUser[TFieldName],
195
- ) => void;
196
-
197
- /**
198
- * Step labels shown in the create-server wizard.
199
- *
200
- * @private function of <ServersClient/>
201
- */
202
- export const CREATE_SERVER_WIZARD_STEPS = [
203
- {
204
- title: 'Profile',
205
- description: 'Name, identifier, environment, domain, and branding.',
206
- },
207
- {
208
- title: 'Users',
209
- description: 'Bootstrap admin credentials and optional extra users.',
210
- },
211
- {
212
- title: 'Settings',
213
- description: 'Language, homepage message, and initial feature flags.',
214
- },
215
- ] as const;
216
-
217
- /**
218
- * Boolean settings rendered as checkbox cards in the final wizard step.
219
- *
220
- * @private function of <ServersClient/>
221
- */
222
- type CreateServerBooleanFeatureFlagKey = keyof Pick<
223
- CreateServerInitialSettings,
224
- 'isFileAttachmentsEnabled' | 'isExperimentalPwaAppEnabled' | 'isFooterShown'
225
- >;
226
-
227
- /**
228
- * Boolean feature flags exposed in the create-server wizard.
229
- *
230
- * @private function of <ServersClient/>
231
- */
232
- export const CREATE_SERVER_BOOLEAN_FEATURE_FLAGS: ReadonlyArray<{
233
- readonly key: CreateServerBooleanFeatureFlagKey;
234
- readonly title: string;
235
- readonly description: string;
236
- }> = [
237
- {
238
- key: 'isFileAttachmentsEnabled',
239
- title: 'File attachments enabled',
240
- description: 'Allow chat attachments on the new server.',
241
- },
242
- {
243
- key: 'isExperimentalPwaAppEnabled',
244
- title: 'PWA install enabled',
245
- description: 'Expose the experimental install-as-app option.',
246
- },
247
- {
248
- key: 'isFooterShown',
249
- title: 'Footer shown',
250
- description: 'Render the shared footer on public pages.',
251
- },
252
- ] as const;
253
-
254
163
  /**
255
164
  * Hook options used to coordinate post-create refresh behavior.
256
165
  *
@@ -269,16 +178,6 @@ type UseCreateServerWizardOptions = {
269
178
  * @private function of <ServersClient/>
270
179
  */
271
180
  type UseCreateServerWizardResult = {
272
- /**
273
- * Adds a new extra bootstrap user row.
274
- */
275
- readonly addAdditionalUser: () => void;
276
-
277
- /**
278
- * Derived table-prefix preview for the current identifier.
279
- */
280
- readonly derivedWizardTablePrefix: string;
281
-
282
181
  /**
283
182
  * Persists the wizard as a new registered server.
284
183
  */
@@ -289,21 +188,6 @@ type UseCreateServerWizardResult = {
289
188
  */
290
189
  readonly handleIconUpload: (event: ChangeEvent<HTMLInputElement>) => Promise<void>;
291
190
 
292
- /**
293
- * Moves the wizard one step backward.
294
- */
295
- readonly handleWizardBack: () => void;
296
-
297
- /**
298
- * Moves the wizard one step forward after validating the current step.
299
- */
300
- readonly handleWizardNext: () => Promise<void>;
301
-
302
- /**
303
- * Navigates to the requested wizard step with step validation.
304
- */
305
- readonly handleWizardStepSelection: (nextStep: number) => Promise<void>;
306
-
307
191
  /**
308
192
  * Hidden file input used for icon uploads.
309
193
  */
@@ -334,11 +218,6 @@ type UseCreateServerWizardResult = {
334
218
  */
335
219
  readonly openDialog: () => void;
336
220
 
337
- /**
338
- * Removes one extra bootstrap user row.
339
- */
340
- readonly removeAdditionalUser: (index: number) => void;
341
-
342
221
  /**
343
222
  * Closes the dialog while respecting the dirty-state guard.
344
223
  */
@@ -349,21 +228,6 @@ type UseCreateServerWizardResult = {
349
228
  */
350
229
  readonly resetWizard: () => void;
351
230
 
352
- /**
353
- * Updates one extra bootstrap user row.
354
- */
355
- readonly updateAdditionalUser: UpdateCreateServerAdditionalUser;
356
-
357
- /**
358
- * Updates the required admin-user fields.
359
- */
360
- readonly updateAdminUser: UpdateCreateServerAdminField;
361
-
362
- /**
363
- * Updates one initial setting field.
364
- */
365
- readonly updateInitialSetting: UpdateCreateServerInitialSetting;
366
-
367
231
  /**
368
232
  * Updates one top-level wizard field.
369
233
  */
@@ -378,26 +242,8 @@ type UseCreateServerWizardResult = {
378
242
  * Current create-server form state.
379
243
  */
380
244
  readonly wizardState: CreateServerWizardState;
381
-
382
- /**
383
- * Current wizard step index.
384
- */
385
- readonly wizardStep: number;
386
245
  };
387
246
 
388
- /**
389
- * Creates an empty extra-user row for the create-server wizard.
390
- *
391
- * @returns Fresh extra-user draft.
392
- */
393
- function createEmptyWizardUser(): WizardUser {
394
- return {
395
- username: '',
396
- password: '',
397
- isAdmin: false,
398
- };
399
- }
400
-
401
247
  /**
402
248
  * Creates the initial create-server wizard state.
403
249
  *
@@ -407,7 +253,7 @@ function createInitialWizardState(): CreateServerWizardState {
407
253
  return {
408
254
  name: '',
409
255
  identifier: '',
410
- environment: 'PREVIEW',
256
+ environment: 'PRODUCTION',
411
257
  domain: '',
412
258
  iconUrl: '',
413
259
  adminUser: {
@@ -426,6 +272,22 @@ function createInitialWizardState(): CreateServerWizardState {
426
272
  };
427
273
  }
428
274
 
275
+ /**
276
+ * Derives a URL-safe server identifier from the visible server name.
277
+ *
278
+ * @param name - Raw server name.
279
+ * @returns Lowercase hyphenated identifier.
280
+ */
281
+ function createServerIdentifierFromName(name: string): string {
282
+ return name
283
+ .normalize('NFKD')
284
+ .replace(/[\u0300-\u036f]/gu, '')
285
+ .toLowerCase()
286
+ .replace(/[^a-z0-9]+/gu, '-')
287
+ .replace(/^-+|-+$/gu, '')
288
+ .replace(/-+/gu, '-');
289
+ }
290
+
429
291
  /**
430
292
  * Safely derives the table-prefix preview for a wizard identifier.
431
293
  *
@@ -446,60 +308,24 @@ function deriveWizardTablePrefix(identifier: string): string {
446
308
  }
447
309
 
448
310
  /**
449
- * Validates the create-server wizard up to the requested step.
311
+ * Validates the simplified create-server wizard.
450
312
  *
451
313
  * @param wizardState - Current wizard form data.
452
- * @param derivedTablePrefix - Derived prefix preview for the current identifier.
453
- * @param upToStep - Highest wizard step that must be valid.
314
+ * @param derivedTablePrefix - Derived prefix preview for the generated identifier.
454
315
  * @returns User-facing validation message or `null` when valid.
455
316
  */
456
317
  function getCreateServerWizardValidationMessage(
457
318
  wizardState: CreateServerWizardState,
458
319
  derivedTablePrefix: string,
459
- upToStep: number,
460
320
  ): string | null {
461
- if (upToStep >= 0) {
462
- if (wizardState.name.trim() === '') {
463
- return 'Server name is required.';
464
- }
465
- if (wizardState.identifier.trim() === '') {
466
- return 'Server identifier is required.';
467
- }
468
- if (!derivedTablePrefix) {
469
- return 'Server identifier must contain only lowercase letters, numbers, and hyphens.';
470
- }
471
- if (wizardState.domain.trim() === '') {
472
- return 'Server domain is required.';
473
- }
321
+ if (wizardState.name.trim() === '') {
322
+ return 'Server name is required.';
474
323
  }
475
-
476
- if (upToStep >= 1) {
477
- if (wizardState.adminUser.username.trim() === '') {
478
- return 'Admin username is required.';
479
- }
480
- if (wizardState.adminUser.password === '') {
481
- return 'Admin password is required.';
482
- }
483
-
484
- const seenUsernames = new Set<string>([wizardState.adminUser.username.trim().toLowerCase()]);
485
- for (const [index, user] of wizardState.additionalUsers.entries()) {
486
- if (user.username.trim() === '') {
487
- return `Additional user ${index + 1} must have a username.`;
488
- }
489
- if (user.password === '') {
490
- return `Additional user ${index + 1} must have a password.`;
491
- }
492
-
493
- const normalizedUsername = user.username.trim().toLowerCase();
494
- if (seenUsernames.has(normalizedUsername)) {
495
- return `Username "${user.username.trim()}" is duplicated in the bootstrap users list.`;
496
- }
497
- seenUsernames.add(normalizedUsername);
498
- }
324
+ if (wizardState.identifier.trim() === '' || !derivedTablePrefix) {
325
+ return 'Server name must contain at least one letter or number.';
499
326
  }
500
-
501
- if (upToStep >= 2 && wizardState.initialSettings.language.trim() === '') {
502
- return 'Initial language is required.';
327
+ if (wizardState.domain.trim() === '') {
328
+ return 'Server domain is required.';
503
329
  }
504
330
 
505
331
  return null;
@@ -509,40 +335,21 @@ function getCreateServerWizardValidationMessage(
509
335
  * Returns whether the create-server wizard contains unsaved values.
510
336
  *
511
337
  * @param wizardState - Current wizard form state.
512
- * @returns `true` when any wizard field differs from its initial value.
338
+ * @returns `true` when any visible wizard field differs from its initial value.
513
339
  */
514
340
  function hasCreateServerWizardChanges(wizardState: CreateServerWizardState): boolean {
515
341
  const initialWizardState = createInitialWizardState();
516
342
 
517
- if (
343
+ return (
518
344
  wizardState.name !== initialWizardState.name ||
519
345
  wizardState.identifier !== initialWizardState.identifier ||
520
- wizardState.environment !== initialWizardState.environment ||
521
346
  wizardState.domain !== initialWizardState.domain ||
522
- wizardState.iconUrl !== initialWizardState.iconUrl ||
523
- wizardState.adminUser.username !== initialWizardState.adminUser.username ||
524
- wizardState.adminUser.password !== initialWizardState.adminUser.password ||
525
- wizardState.initialSettings.language !== initialWizardState.initialSettings.language ||
526
- wizardState.initialSettings.homepageMessage !== initialWizardState.initialSettings.homepageMessage ||
527
- wizardState.initialSettings.feedbackMode !== initialWizardState.initialSettings.feedbackMode ||
528
- wizardState.initialSettings.isFileAttachmentsEnabled !==
529
- initialWizardState.initialSettings.isFileAttachmentsEnabled ||
530
- wizardState.initialSettings.isExperimentalPwaAppEnabled !==
531
- initialWizardState.initialSettings.isExperimentalPwaAppEnabled ||
532
- wizardState.initialSettings.isFooterShown !== initialWizardState.initialSettings.isFooterShown
533
- ) {
534
- return true;
535
- }
536
-
537
- if (wizardState.additionalUsers.length !== initialWizardState.additionalUsers.length) {
538
- return true;
539
- }
540
-
541
- return wizardState.additionalUsers.some((user) => user.username !== '' || user.password !== '' || user.isAdmin);
347
+ wizardState.iconUrl !== initialWizardState.iconUrl
348
+ );
542
349
  }
543
350
 
544
351
  /**
545
- * Encapsulates the multi-step create-server dialog state and side effects.
352
+ * Encapsulates the simplified create-server dialog state and side effects.
546
353
  *
547
354
  * @param options - Hook options.
548
355
  * @returns Dialog state, derived values, and event handlers.
@@ -552,7 +359,6 @@ function hasCreateServerWizardChanges(wizardState: CreateServerWizardState): boo
552
359
  export function useCreateServerWizard(options: UseCreateServerWizardOptions): UseCreateServerWizardResult {
553
360
  const { onServerCreated } = options;
554
361
  const [isDialogOpen, setIsDialogOpen] = useState(false);
555
- const [wizardStep, setWizardStep] = useState(0);
556
362
  const [wizardState, setWizardState] = useState<CreateServerWizardState>(createInitialWizardState);
557
363
  const [isCreatingServer, setIsCreatingServer] = useState(false);
558
364
  const [wizardError, setWizardError] = useState<CreateServerWizardError | null>(null);
@@ -566,7 +372,6 @@ export function useCreateServerWizard(options: UseCreateServerWizardOptions): Us
566
372
  const isDirty = useMemo(() => hasCreateServerWizardChanges(wizardState), [wizardState]);
567
373
 
568
374
  const resetWizard = useCallback(() => {
569
- setWizardStep(0);
570
375
  setWizardState(createInitialWizardState());
571
376
  setWizardError(null);
572
377
 
@@ -593,53 +398,20 @@ export function useCreateServerWizard(options: UseCreateServerWizardOptions): Us
593
398
  }, [resetWizard]);
594
399
 
595
400
  const updateWizardField = useCallback<UpdateCreateServerWizardField>((fieldName, value) => {
596
- setWizardState((previous) => ({
597
- ...previous,
598
- [fieldName]: value,
599
- }));
600
- }, []);
601
-
602
- const updateAdminUser = useCallback<UpdateCreateServerAdminField>((fieldName, value) => {
603
- setWizardState((previous) => ({
604
- ...previous,
605
- adminUser: {
606
- ...previous.adminUser,
607
- [fieldName]: value,
608
- },
609
- }));
610
- }, []);
401
+ setWizardState((previous) => {
402
+ if (fieldName === 'name') {
403
+ return {
404
+ ...previous,
405
+ name: value,
406
+ identifier: createServerIdentifierFromName(value),
407
+ };
408
+ }
611
409
 
612
- const updateInitialSetting = useCallback<UpdateCreateServerInitialSetting>((fieldName, value) => {
613
- setWizardState((previous) => ({
614
- ...previous,
615
- initialSettings: {
616
- ...previous.initialSettings,
410
+ return {
411
+ ...previous,
617
412
  [fieldName]: value,
618
- },
619
- }));
620
- }, []);
621
-
622
- const updateAdditionalUser = useCallback<UpdateCreateServerAdditionalUser>((index, fieldName, value) => {
623
- setWizardState((previous) => ({
624
- ...previous,
625
- additionalUsers: previous.additionalUsers.map((user, userIndex) =>
626
- userIndex === index ? { ...user, [fieldName]: value } : user,
627
- ),
628
- }));
629
- }, []);
630
-
631
- const addAdditionalUser = useCallback(() => {
632
- setWizardState((previous) => ({
633
- ...previous,
634
- additionalUsers: [...previous.additionalUsers, createEmptyWizardUser()],
635
- }));
636
- }, []);
637
-
638
- const removeAdditionalUser = useCallback((index: number) => {
639
- setWizardState((previous) => ({
640
- ...previous,
641
- additionalUsers: previous.additionalUsers.filter((_, userIndex) => userIndex !== index),
642
- }));
413
+ };
414
+ });
643
415
  }, []);
644
416
 
645
417
  const handleIconUpload = useCallback(
@@ -686,11 +458,7 @@ export function useCreateServerWizard(options: UseCreateServerWizardOptions): Us
686
458
  );
687
459
 
688
460
  const handleCreateServer = useCallback(async () => {
689
- const validationMessage = getCreateServerWizardValidationMessage(
690
- wizardState,
691
- derivedWizardTablePrefix,
692
- CREATE_SERVER_WIZARD_STEPS.length - 1,
693
- );
461
+ const validationMessage = getCreateServerWizardValidationMessage(wizardState, derivedWizardTablePrefix);
694
462
  if (validationMessage) {
695
463
  await showAlert({
696
464
  title: 'Create server',
@@ -739,75 +507,19 @@ export function useCreateServerWizard(options: UseCreateServerWizardOptions): Us
739
507
  }
740
508
  }, [closeDialog, derivedWizardTablePrefix, onServerCreated, wizardState]);
741
509
 
742
- const handleWizardBack = useCallback(() => {
743
- setWizardStep((previous) => Math.max(0, previous - 1));
744
- }, []);
745
-
746
- const handleWizardNext = useCallback(async () => {
747
- const validationMessage = getCreateServerWizardValidationMessage(
748
- wizardState,
749
- derivedWizardTablePrefix,
750
- wizardStep,
751
- );
752
- if (validationMessage) {
753
- await showAlert({
754
- title: 'Create server',
755
- message: validationMessage,
756
- }).catch(() => undefined);
757
- return;
758
- }
759
-
760
- setWizardStep((previous) => Math.min(CREATE_SERVER_WIZARD_STEPS.length - 1, previous + 1));
761
- }, [derivedWizardTablePrefix, wizardState, wizardStep]);
762
-
763
- const handleWizardStepSelection = useCallback(
764
- async (nextStep: number) => {
765
- if (nextStep <= wizardStep) {
766
- setWizardStep(nextStep);
767
- return;
768
- }
769
-
770
- const validationMessage = getCreateServerWizardValidationMessage(
771
- wizardState,
772
- derivedWizardTablePrefix,
773
- wizardStep,
774
- );
775
- if (validationMessage) {
776
- await showAlert({
777
- title: 'Create server',
778
- message: validationMessage,
779
- }).catch(() => undefined);
780
- return;
781
- }
782
-
783
- setWizardStep(nextStep);
784
- },
785
- [derivedWizardTablePrefix, wizardState, wizardStep],
786
- );
787
-
788
510
  return {
789
- addAdditionalUser,
790
- derivedWizardTablePrefix,
791
511
  handleCreateServer,
792
512
  handleIconUpload,
793
- handleWizardBack,
794
- handleWizardNext,
795
- handleWizardStepSelection,
796
513
  iconInputRef,
797
514
  isCreatingServer,
798
515
  isDialogOpen,
799
516
  isDirty,
800
517
  isUploadingIcon,
801
518
  openDialog,
802
- removeAdditionalUser,
803
519
  requestClose,
804
520
  resetWizard,
805
- updateAdditionalUser,
806
- updateAdminUser,
807
- updateInitialSetting,
808
521
  updateWizardField,
809
522
  wizardError,
810
523
  wizardState,
811
- wizardStep,
812
524
  };
813
525
  }
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { useCallback, useEffect, useMemo, useState } from 'react';
4
4
  import { showAlert, showConfirm, showPrompt } from '../../../components/AsyncDialogs/asyncDialogs';
5
+ import type { ManagedServerDnsDiagnostic } from './ServersRegistryDnsTypes';
5
6
  import { ServersRegistryApi } from './ServersRegistryApi';
6
7
 
7
8
  /**
@@ -63,6 +64,11 @@ export type ManagedServerRow = {
63
64
  * Last update timestamp.
64
65
  */
65
66
  readonly updatedAt: string;
67
+
68
+ /**
69
+ * Optional standalone-VPS DNS verification details for the domain.
70
+ */
71
+ readonly dnsDiagnostic?: ManagedServerDnsDiagnostic | null;
66
72
  };
67
73
 
68
74
  /**
@@ -178,6 +184,11 @@ type UseServersRegistryStateResult = {
178
184
  */
179
185
  readonly loading: boolean;
180
186
 
187
+ /**
188
+ * Whether the registry rows are virtual standalone VPS domains.
189
+ */
190
+ readonly isStandaloneVps: boolean;
191
+
181
192
  /**
182
193
  * Server id currently running migrations.
183
194
  */
@@ -433,6 +444,7 @@ function useServersRegistryDraftState(servers: ReadonlyArray<ManagedServerRow>)
433
444
  * @private function of useServersRegistryState
434
445
  */
435
446
  function useServersRegistryReloadAction(options: {
447
+ readonly setIsStandaloneVps: (isStandaloneVps: boolean) => void;
436
448
  readonly replaceServerDrafts: (servers: ReadonlyArray<ManagedServerRow>) => void;
437
449
  readonly setCanEdit: (canEdit: boolean) => void;
438
450
  readonly setCurrentServerId: (currentServerId: number | null) => void;
@@ -440,7 +452,15 @@ function useServersRegistryReloadAction(options: {
440
452
  readonly setLoading: (isLoading: boolean) => void;
441
453
  readonly setServers: (servers: ManagedServerRow[]) => void;
442
454
  }) {
443
- const { replaceServerDrafts, setCanEdit, setCurrentServerId, setError, setLoading, setServers } = options;
455
+ const {
456
+ replaceServerDrafts,
457
+ setCanEdit,
458
+ setCurrentServerId,
459
+ setError,
460
+ setIsStandaloneVps,
461
+ setLoading,
462
+ setServers,
463
+ } = options;
444
464
 
445
465
  return useCallback(async () => {
446
466
  setLoading(true);
@@ -451,13 +471,14 @@ function useServersRegistryReloadAction(options: {
451
471
  setServers([...payload.servers]);
452
472
  setCurrentServerId(payload.currentServerId);
453
473
  setCanEdit(payload.canEdit);
474
+ setIsStandaloneVps(payload.isStandaloneVps === true);
454
475
  replaceServerDrafts(payload.servers);
455
476
  } catch (loadError) {
456
477
  setError(resolveServersRegistryActionErrorMessage(loadError, 'Failed to load servers.'));
457
478
  } finally {
458
479
  setLoading(false);
459
480
  }
460
- }, [replaceServerDrafts, setCanEdit, setCurrentServerId, setError, setLoading, setServers]);
481
+ }, [replaceServerDrafts, setCanEdit, setCurrentServerId, setError, setIsStandaloneVps, setLoading, setServers]);
461
482
  }
462
483
 
463
484
  /**
@@ -626,6 +647,7 @@ function useDeleteCurrentServerAction(options: {
626
647
  export function useServersRegistryState(): UseServersRegistryStateResult {
627
648
  const [servers, setServers] = useState<ManagedServerRow[]>([]);
628
649
  const [canEdit, setCanEdit] = useState(false);
650
+ const [isStandaloneVps, setIsStandaloneVps] = useState(false);
629
651
  const [loading, setLoading] = useState(true);
630
652
  const [error, setError] = useState<string | null>(null);
631
653
  const [currentServerId, setCurrentServerId] = useState<number | null>(null);
@@ -646,6 +668,7 @@ export function useServersRegistryState(): UseServersRegistryStateResult {
646
668
  setCanEdit,
647
669
  setCurrentServerId,
648
670
  setError,
671
+ setIsStandaloneVps,
649
672
  setLoading,
650
673
  setServers,
651
674
  });
@@ -688,6 +711,7 @@ export function useServersRegistryState(): UseServersRegistryStateResult {
688
711
  error,
689
712
  hasDirtyServerDrafts,
690
713
  isServerDraftDirty,
714
+ isStandaloneVps,
691
715
  loading,
692
716
  migrateServer,
693
717
  migratingServerId,