rivet-design 0.14.13 → 0.14.14

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 (71) hide show
  1. package/dist/agent-variants/contracts.d.ts +30 -30
  2. package/dist/cli/commands/mcpServe.d.ts +1 -1
  3. package/dist/index.d.ts +0 -9
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +1 -96
  6. package/dist/index.js.map +1 -1
  7. package/dist/proxy-middleware/proxy-config.d.ts.map +1 -1
  8. package/dist/proxy-middleware/proxy-config.js +33 -19
  9. package/dist/proxy-middleware/proxy-config.js.map +1 -1
  10. package/dist/server.d.ts +0 -19
  11. package/dist/server.d.ts.map +1 -1
  12. package/dist/server.js +17 -491
  13. package/dist/server.js.map +1 -1
  14. package/dist/services/AuthService.d.ts +1 -1
  15. package/dist/services/AuthService.d.ts.map +1 -1
  16. package/dist/services/AuthService.js +5 -4
  17. package/dist/services/AuthService.js.map +1 -1
  18. package/dist/services/MCPOnboardingTelemetry.d.ts +2 -2
  19. package/dist/services/MCPOnboardingTelemetry.d.ts.map +1 -1
  20. package/dist/services/MCPOnboardingTelemetry.js +0 -3
  21. package/dist/services/MCPOnboardingTelemetry.js.map +1 -1
  22. package/dist/services/TelemetryService.d.ts +1 -96
  23. package/dist/services/TelemetryService.d.ts.map +1 -1
  24. package/dist/services/TelemetryService.js +0 -198
  25. package/dist/services/TelemetryService.js.map +1 -1
  26. package/dist/services/accessTokenRefresh.d.ts +0 -11
  27. package/dist/services/accessTokenRefresh.d.ts.map +1 -1
  28. package/dist/services/accessTokenRefresh.js +4 -24
  29. package/dist/services/accessTokenRefresh.js.map +1 -1
  30. package/package.json +1 -3
  31. package/src/ui/dist/assets/main-CHUtDutm.js +422 -0
  32. package/src/ui/dist/assets/main-CrLtwwgK.css +1 -0
  33. package/src/ui/dist/index.html +2 -2
  34. package/dist/demo/sessionRuntime.d.ts +0 -2
  35. package/dist/demo/sessionRuntime.d.ts.map +0 -1
  36. package/dist/demo/sessionRuntime.js +0 -48
  37. package/dist/demo/sessionRuntime.js.map +0 -1
  38. package/dist/hosted-demo.d.ts +0 -2
  39. package/dist/hosted-demo.d.ts.map +0 -1
  40. package/dist/hosted-demo.js +0 -83
  41. package/dist/hosted-demo.js.map +0 -1
  42. package/dist/routes/demo.d.ts +0 -33
  43. package/dist/routes/demo.d.ts.map +0 -1
  44. package/dist/routes/demo.js +0 -180
  45. package/dist/routes/demo.js.map +0 -1
  46. package/dist/services/HostedDemoAuthSessionService.d.ts +0 -50
  47. package/dist/services/HostedDemoAuthSessionService.d.ts.map +0 -1
  48. package/dist/services/HostedDemoAuthSessionService.js +0 -192
  49. package/dist/services/HostedDemoAuthSessionService.js.map +0 -1
  50. package/dist/services/HostedDemoAuthSessionStore.d.ts +0 -44
  51. package/dist/services/HostedDemoAuthSessionStore.d.ts.map +0 -1
  52. package/dist/services/HostedDemoAuthSessionStore.js +0 -90
  53. package/dist/services/HostedDemoAuthSessionStore.js.map +0 -1
  54. package/dist/services/HostedDemoSessionService.d.ts +0 -91
  55. package/dist/services/HostedDemoSessionService.d.ts.map +0 -1
  56. package/dist/services/HostedDemoSessionService.js +0 -568
  57. package/dist/services/HostedDemoSessionService.js.map +0 -1
  58. package/dist/services/HostedDemoSessionStore.d.ts +0 -49
  59. package/dist/services/HostedDemoSessionStore.d.ts.map +0 -1
  60. package/dist/services/HostedDemoSessionStore.js +0 -90
  61. package/dist/services/HostedDemoSessionStore.js.map +0 -1
  62. package/dist/services/hostedDemoSessionAuthRefresh.d.ts +0 -18
  63. package/dist/services/hostedDemoSessionAuthRefresh.d.ts.map +0 -1
  64. package/dist/services/hostedDemoSessionAuthRefresh.js +0 -39
  65. package/dist/services/hostedDemoSessionAuthRefresh.js.map +0 -1
  66. package/dist/utils/shouldRecordHostedDemoSessionAction.d.ts +0 -8
  67. package/dist/utils/shouldRecordHostedDemoSessionAction.d.ts.map +0 -1
  68. package/dist/utils/shouldRecordHostedDemoSessionAction.js +0 -11
  69. package/dist/utils/shouldRecordHostedDemoSessionAction.js.map +0 -1
  70. package/src/ui/dist/assets/main-BfVGaiD6.js +0 -422
  71. package/src/ui/dist/assets/main-CobdEReL.css +0 -1
package/dist/server.js CHANGED
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.startServer = exports.runServerShutdownTasks = exports.isRivetCorsOriginAllowed = exports.isRivetUiStaticAssetPath = exports.isEmbeddedAgentUiHost = exports.resolveEmbeddedAgentPreviewOrigin = exports.resolveEmbeddedAgentUiOrigin = exports.resolveRivetListenHost = exports.sendInactiveVariantsEventStream = exports.readRivetUiIndexHtml = exports.isHostedRootApiPath = exports.isDemoAuthExemptApiPath = exports.injectRivetUiBootstrap = exports.DIST_UI_PATH = exports.RIVET_CORS_ALLOWED_HEADERS = exports.INACTIVE_VARIANTS_EVENT_HEARTBEAT_MS = void 0;
39
+ exports.startServer = exports.runServerShutdownTasks = exports.isRivetCorsOriginAllowed = exports.isRivetUiStaticAssetPath = exports.isEmbeddedAgentUiHost = exports.resolveEmbeddedAgentPreviewOrigin = exports.resolveEmbeddedAgentUiOrigin = exports.resolveRivetListenHost = exports.sendInactiveVariantsEventStream = exports.readRivetUiIndexHtml = exports.injectRivetUiBootstrap = exports.DIST_UI_PATH = exports.RIVET_CORS_ALLOWED_HEADERS = exports.INACTIVE_VARIANTS_EVENT_HEARTBEAT_MS = void 0;
40
40
  const Sentry = __importStar(require("@sentry/node"));
41
41
  const express_1 = __importDefault(require("express"));
42
42
  const cors_1 = __importDefault(require("cors"));
@@ -54,7 +54,6 @@ const proxy_config_1 = require("./proxy-middleware/proxy-config");
54
54
  const StaticFileService_1 = require("./services/StaticFileService");
55
55
  const static_1 = require("./routes/static");
56
56
  const ConfigManager_1 = require("./services/ConfigManager");
57
- const accessTokenRefresh_1 = require("./services/accessTokenRefresh");
58
57
  const evaluateFlags_1 = require("./config/evaluateFlags");
59
58
  const FeatureFlagService_1 = require("./services/FeatureFlagService");
60
59
  const DesktopVersionPolicyService_1 = require("./services/DesktopVersionPolicyService");
@@ -67,14 +66,6 @@ const serverHandshake_1 = require("./cli/serverHandshake");
67
66
  const telemetry_1 = require("./config/telemetry");
68
67
  const HistoryReplayService_1 = require("./services/HistoryReplayService");
69
68
  const VariantHistoryService_1 = require("./services/VariantHistoryService");
70
- const demo_1 = require("./routes/demo");
71
- const HostedDemoSessionService_1 = require("./services/HostedDemoSessionService");
72
- const HostedDemoSessionStore_1 = require("./services/HostedDemoSessionStore");
73
- const http_proxy_middleware_1 = require("http-proxy-middleware");
74
- const HostedDemoAuthSessionService_1 = require("./services/HostedDemoAuthSessionService");
75
- const HostedDemoAuthSessionStore_1 = require("./services/HostedDemoAuthSessionStore");
76
- const shouldRecordHostedDemoSessionAction_1 = require("./utils/shouldRecordHostedDemoSessionAction");
77
- const hostedDemoSessionAuthRefresh_1 = require("./services/hostedDemoSessionAuthRefresh");
78
69
  const RequestAuthContext_1 = require("./services/RequestAuthContext");
79
70
  const log = (0, index_core_1.createLogger)('RivetServer');
80
71
  const QUEUE_ACCESS_TOKEN_BYTES = 32;
@@ -138,33 +129,6 @@ const injectRivetUiBootstrap = (html, bootstrap) => {
138
129
  return `${script}${html}`;
139
130
  };
140
131
  exports.injectRivetUiBootstrap = injectRivetUiBootstrap;
141
- const isDemoAuthExemptApiPath = (pathName) => {
142
- if (pathName === '/config' ||
143
- pathName === '/feature-flags' ||
144
- pathName === '/health' ||
145
- pathName === '/auth/store') {
146
- return true;
147
- }
148
- if (pathName === '/demo/session' || pathName.startsWith('/demo/session/')) {
149
- return true;
150
- }
151
- return false;
152
- };
153
- exports.isDemoAuthExemptApiPath = isDemoAuthExemptApiPath;
154
- const isHostedRootApiPath = (pathName) => {
155
- if (pathName === '/config' ||
156
- pathName === '/feature-flags' ||
157
- pathName === '/health' ||
158
- pathName === '/auth/store' ||
159
- pathName === '/support') {
160
- return true;
161
- }
162
- if (pathName === '/demo/session' || pathName.startsWith('/demo/session/')) {
163
- return true;
164
- }
165
- return false;
166
- };
167
- exports.isHostedRootApiPath = isHostedRootApiPath;
168
132
  /**
169
133
  * Reads the Rivet UI entry document that references the active built assets.
170
134
  */
@@ -284,9 +248,7 @@ const startServer = async (options) => {
284
248
  const userPortWithFallback = userPort ?? _1.DEFAULT_USER_PORT;
285
249
  const userHostWithFallback = userHost ?? 'localhost';
286
250
  const hasUserDevServer = typeof userPort === 'number' && Number.isInteger(userPort) && userPort > 0;
287
- const isDemoModeEnabled = options.demoMode?.enabled ?? false;
288
- const requiresDemoAuth = options.demoMode?.requireSignedInUsers ?? true;
289
- const isGitEnabled = options.isGitEnabled ?? !isDemoModeEnabled;
251
+ const isGitEnabled = options.isGitEnabled ?? true;
290
252
  const queueAccessToken = sessionBridge && agentApplyMode === 'embedded'
291
253
  ? (0, crypto_1.randomBytes)(QUEUE_ACCESS_TOKEN_BYTES).toString('base64url')
292
254
  : null;
@@ -336,9 +298,7 @@ const startServer = async (options) => {
336
298
  const shutdownAndExit = async (code) => {
337
299
  log.info('Server shutting down, cleaning up...');
338
300
  (0, WorktreeManager_1.cleanupOrphanedWorktrees)();
339
- if (!isDemoModeEnabled) {
340
- (0, serverHandshake_1.removeHandshake)(projectPath, process.pid);
341
- }
301
+ (0, serverHandshake_1.removeHandshake)(projectPath, process.pid);
342
302
  const results = await Promise.allSettled([
343
303
  options.beforeShutdown?.(),
344
304
  telemetry?.shutdown(),
@@ -386,10 +346,6 @@ const startServer = async (options) => {
386
346
  .filter((origin) => origin.length > 0)
387
347
  .forEach((origin) => corsOrigins.add(origin));
388
348
  }
389
- if (isDemoModeEnabled) {
390
- corsOrigins.add('https://rivet.design');
391
- corsOrigins.add('https://demo.rivet.design');
392
- }
393
349
  // CORS configuration for local development
394
350
  app.use((req, res, next) => {
395
351
  (0, cors_1.default)({
@@ -429,13 +385,7 @@ const startServer = async (options) => {
429
385
  });
430
386
  }
431
387
  const jsonBodyParser = express_1.default.json({ limit: '50mb' });
432
- app.use((req, res, next) => {
433
- if (req.originalUrl.startsWith('/try/')) {
434
- next();
435
- return;
436
- }
437
- jsonBodyParser(req, res, next);
438
- });
388
+ app.use(jsonBodyParser);
439
389
  // Request logging middleware
440
390
  app.use((req, res, next) => {
441
391
  log.debug(`${req.method} ${req.originalUrl}`);
@@ -480,7 +430,7 @@ const startServer = async (options) => {
480
430
  // Serve hashed UI assets from root so both / and /rivet entrypoints can load them.
481
431
  app.use('/assets', express_1.default.static(path_1.default.join(exports.DIST_UI_PATH, 'assets'), uiStaticOptions));
482
432
  app.use('/rivet/assets', express_1.default.static(path_1.default.join(exports.DIST_UI_PATH, 'assets'), uiStaticOptions));
483
- // Serve public font files used by auth and hosted demo UI.
433
+ // Serve public font files used by the auth UI.
484
434
  app.use('/fonts', express_1.default.static(path_1.default.join(exports.DIST_UI_PATH, 'fonts'), uiStaticOptions));
485
435
  app.use('/rivet/fonts', express_1.default.static(path_1.default.join(exports.DIST_UI_PATH, 'fonts'), uiStaticOptions));
486
436
  // Serve favicon at root for hosted/static deployments.
@@ -491,7 +441,7 @@ const startServer = async (options) => {
491
441
  res.sendFile('favicon.ico', { root: exports.DIST_UI_PATH });
492
442
  });
493
443
  // Serve Rivet UI at /rivet for every mode; static apps use /static for the
494
- // user project preview and still need the hosted demo UI at /rivet.
444
+ // user project preview and still need the editor UI at /rivet.
495
445
  app.get(/^\/rivet(?:\/.*)?$/, (req, res, next) => {
496
446
  if ((0, exports.isRivetUiStaticAssetPath)(req.path)) {
497
447
  next();
@@ -548,195 +498,6 @@ const startServer = async (options) => {
548
498
  next();
549
499
  });
550
500
  });
551
- const demoAuthSessionService = isDemoModeEnabled
552
- ? new HostedDemoAuthSessionService_1.HostedDemoAuthSessionService({
553
- store: options.demoMode?.authRedisUrl
554
- ? new HostedDemoAuthSessionStore_1.RedisHostedDemoAuthSessionStore({
555
- redisUrl: options.demoMode.authRedisUrl,
556
- keyPrefix: options.demoMode.authRedisKeyPrefix ??
557
- 'rivet:hosted-demo:auth-session',
558
- })
559
- : undefined,
560
- })
561
- : null;
562
- if (demoAuthSessionService) {
563
- await demoAuthSessionService.initialize();
564
- }
565
- if (demoAuthSessionService) {
566
- app.use(async (req, res, next) => {
567
- try {
568
- const sessionId = demoAuthSessionService.getOrCreateSessionId(req, res);
569
- const auth = await (0, hostedDemoSessionAuthRefresh_1.resolveHostedDemoSessionAuthWithRefresh)({
570
- demoAuthSessionService,
571
- sessionId,
572
- res,
573
- getProxyUrl: () => (0, ConfigManager_1.getConfigManager)().getProxyUrl(),
574
- });
575
- const headerToken = getBearerTokenFromHeader(req.headers.authorization);
576
- res.locals.demoAuthSessionId = sessionId;
577
- (0, RequestAuthContext_1.runWithRequestAuthContext)({
578
- token: auth?.token ?? headerToken,
579
- refreshToken: auth?.refreshToken,
580
- email: auth?.email,
581
- }, () => {
582
- next();
583
- });
584
- }
585
- catch (error) {
586
- next(error);
587
- }
588
- });
589
- }
590
- const isDemoRequestAuthenticated = (req) => {
591
- if (!isDemoModeEnabled || !requiresDemoAuth) {
592
- return true;
593
- }
594
- return Boolean(demoAuthSessionService?.getAuthForRequest(req));
595
- };
596
- const getDemoRequestOwnerUserId = (req) => {
597
- if (!requiresDemoAuth) {
598
- return null;
599
- }
600
- const cookieAuthEmail = demoAuthSessionService
601
- ?.getAuthForRequest(req)
602
- ?.email?.trim()
603
- .toLowerCase();
604
- if (cookieAuthEmail) {
605
- return cookieAuthEmail;
606
- }
607
- const email = (0, ConfigManager_1.getConfigManager)().getEmail();
608
- if (!email) {
609
- return null;
610
- }
611
- return email.trim().toLowerCase();
612
- };
613
- let demoSessionService = null;
614
- if (isDemoModeEnabled &&
615
- options.demoMode?.allowSessionProvisioning !== false) {
616
- const sessionMetadataRedisUrl = options.demoMode?.sessionMetadataRedisUrl ??
617
- options.demoMode?.authRedisUrl;
618
- const sessionMetadataStore = sessionMetadataRedisUrl
619
- ? new HostedDemoSessionStore_1.RedisHostedDemoSessionStore({
620
- redisUrl: sessionMetadataRedisUrl,
621
- keyPrefix: options.demoMode?.sessionMetadataRedisKeyPrefix ??
622
- 'rivet:hosted-demo:demo-session',
623
- })
624
- : undefined;
625
- demoSessionService = new HostedDemoSessionService_1.HostedDemoSessionService({
626
- repoPath: projectPath,
627
- telemetry,
628
- templateProjectPath: options.demoMode?.templateProjectPath ?? 'examples/microsoft-paint',
629
- worktreesRootPath: options.demoMode?.worktreesRootPath,
630
- sessionTtlMs: options.demoMode?.sessionTtlMs,
631
- sessionIdleTtlMs: options.demoMode?.sessionIdleTtlMs,
632
- maxActiveSessions: options.demoMode?.maxActiveSessions,
633
- baseRivetPort: options.demoMode?.baseRivetPort,
634
- publicBaseUrl: options.demoMode?.publicBaseUrl,
635
- sessionMetadataStore,
636
- });
637
- await demoSessionService.initialize();
638
- }
639
- if (isDemoModeEnabled && requiresDemoAuth) {
640
- app.use('/api', (req, res, next) => {
641
- if ((0, exports.isDemoAuthExemptApiPath)(req.path)) {
642
- next();
643
- return;
644
- }
645
- if (!isDemoRequestAuthenticated(req)) {
646
- res.status(401).json({ error: 'Authentication required' });
647
- return;
648
- }
649
- next();
650
- });
651
- }
652
- if (demoSessionService) {
653
- const activeSessionApiProxy = (0, http_proxy_middleware_1.createProxyMiddleware)({
654
- changeOrigin: true,
655
- pathRewrite: (pathName) => `/api${pathName}`,
656
- on: {
657
- proxyReq: (proxyReq, req) => {
658
- (0, http_proxy_middleware_1.fixRequestBody)(proxyReq, req);
659
- },
660
- },
661
- router: (req) => {
662
- const activeDemoSessionId = demoAuthSessionService?.getActiveDemoSessionIdForRequest(req) ?? null;
663
- if (!activeDemoSessionId) {
664
- return undefined;
665
- }
666
- return (demoSessionService.getSessionProxyTarget(activeDemoSessionId) ??
667
- undefined);
668
- },
669
- });
670
- app.use('/api', (req, res, next) => {
671
- if ((0, exports.isHostedRootApiPath)(req.path)) {
672
- next();
673
- return;
674
- }
675
- const activeDemoSessionId = demoAuthSessionService?.getActiveDemoSessionIdForRequest(req) ?? null;
676
- if (!activeDemoSessionId) {
677
- res.status(409).json({
678
- error: 'No active demo session. Call /api/demo/session first.',
679
- });
680
- return;
681
- }
682
- const sessionOwnerUserId = demoSessionService.getSessionOwnerUserId(activeDemoSessionId);
683
- const requestOwnerUserId = getDemoRequestOwnerUserId(req);
684
- if (requiresDemoAuth &&
685
- sessionOwnerUserId &&
686
- requestOwnerUserId &&
687
- sessionOwnerUserId !== requestOwnerUserId) {
688
- res.status(403).json({ error: 'Session access denied' });
689
- return;
690
- }
691
- const auth = demoAuthSessionService?.getAuthForRequest(req);
692
- if (auth?.token) {
693
- req.headers.authorization = `Bearer ${auth.token}`;
694
- }
695
- void (async () => {
696
- try {
697
- await demoSessionService.ensureRuntimeReady(activeDemoSessionId);
698
- }
699
- catch (error) {
700
- const message = error instanceof Error ? error.message : '';
701
- if (message === 'Session not found') {
702
- demoAuthSessionService?.clearActiveDemoSessionIdForRequest(req, res);
703
- if (!res.headersSent) {
704
- res.status(409).json({
705
- error: 'No active demo session. Call /api/demo/session first.',
706
- });
707
- }
708
- return;
709
- }
710
- log.warn('Hosted demo runtime rehydration failed for active session API', error);
711
- if (!res.headersSent) {
712
- res.status(503).json({
713
- error: 'Demo session runtime unavailable',
714
- });
715
- }
716
- return;
717
- }
718
- const target = demoSessionService.getSessionProxyTarget(activeDemoSessionId);
719
- if (!target) {
720
- demoAuthSessionService?.clearActiveDemoSessionIdForRequest(req, res);
721
- if (!res.headersSent) {
722
- res.status(409).json({
723
- error: 'No active demo session. Call /api/demo/session first.',
724
- });
725
- }
726
- return;
727
- }
728
- if ((0, shouldRecordHostedDemoSessionAction_1.shouldRecordHostedDemoSessionAction)(req)) {
729
- try {
730
- await demoSessionService.recordSessionAction(activeDemoSessionId);
731
- }
732
- catch (error) {
733
- log.warn('Failed to persist hosted demo session action timestamp', error);
734
- }
735
- }
736
- activeSessionApiProxy(req, res, next);
737
- })();
738
- });
739
- }
740
501
  // API routes for Rivet functionality
741
502
  app.use('/api', (0, integrations_1.createIntegrationsRouter)());
742
503
  void (0, WorktreeManager_1.pruneWorktrees)(projectPath); // prune stale registry entries from prior crashes
@@ -747,114 +508,6 @@ const startServer = async (options) => {
747
508
  isGitEnabled,
748
509
  isGatewayLlmEnabled,
749
510
  }));
750
- let trySessionProxy = null;
751
- if (demoSessionService) {
752
- app.use('/api', (0, demo_1.createDemoRouter)(demoSessionService, {
753
- requireSignedInUsers: requiresDemoAuth,
754
- getActiveDemoSessionIdForRequest: demoAuthSessionService
755
- ? (req) => demoAuthSessionService.getActiveDemoSessionIdForRequest(req)
756
- : undefined,
757
- storeActiveDemoSessionIdForRequest: demoAuthSessionService
758
- ? (req, res, demoSessionId) => demoAuthSessionService.storeActiveDemoSessionIdForRequest(req, res, demoSessionId)
759
- : undefined,
760
- clearActiveDemoSessionIdForRequest: demoAuthSessionService
761
- ? (req, res) => demoAuthSessionService.clearActiveDemoSessionIdForRequest(req, res)
762
- : undefined,
763
- telemetry,
764
- deploymentEnv: process.env.NODE_ENV ?? 'development',
765
- }));
766
- const mountedTrySessionProxy = (0, http_proxy_middleware_1.createProxyMiddleware)({
767
- changeOrigin: true,
768
- ws: true,
769
- router: (req) => {
770
- const sessionIdParam = req.params.sessionId;
771
- const sessionId = Array.isArray(sessionIdParam)
772
- ? sessionIdParam[0]
773
- : sessionIdParam;
774
- return demoSessionService.getSessionProxyTarget(sessionId) ?? undefined;
775
- },
776
- });
777
- trySessionProxy = mountedTrySessionProxy;
778
- // Browsers resolve default favicon relative to the document URL under /try/:id/,
779
- // so requests hit this path instead of /. Serve the Rivet UI favicon here too.
780
- app.get('/try/:sessionId/favicon.ico', (_req, res) => {
781
- res.sendFile('favicon.ico', { root: exports.DIST_UI_PATH });
782
- });
783
- app.use('/try/:sessionId', (req, res, next) => {
784
- if (!isDemoRequestAuthenticated(req)) {
785
- if (req.accepts('html')) {
786
- res.redirect('/');
787
- return;
788
- }
789
- res.status(401).json({ error: 'Authentication required' });
790
- return;
791
- }
792
- const sessionIdParam = req.params.sessionId;
793
- const sessionId = Array.isArray(sessionIdParam)
794
- ? sessionIdParam[0]
795
- : sessionIdParam;
796
- const sessionOwnerUserId = demoSessionService.getSessionOwnerUserId(sessionId);
797
- const requestOwnerUserId = getDemoRequestOwnerUserId(req);
798
- if (requiresDemoAuth &&
799
- sessionOwnerUserId &&
800
- requestOwnerUserId &&
801
- sessionOwnerUserId !== requestOwnerUserId) {
802
- res.status(403).json({ error: 'Session access denied' });
803
- return;
804
- }
805
- const auth = demoAuthSessionService?.getAuthForRequest(req);
806
- if (auth?.token) {
807
- req.headers.authorization = `Bearer ${auth.token}`;
808
- }
809
- void (async () => {
810
- try {
811
- await demoSessionService.ensureRuntimeReady(sessionId);
812
- }
813
- catch (error) {
814
- const message = error instanceof Error ? error.message : '';
815
- if (message === 'Session not found') {
816
- demoAuthSessionService?.clearActiveDemoSessionIdForRequest(req, res);
817
- telemetry?.trackTryoutProxySessionMissing({
818
- demoSessionId: sessionId,
819
- deploymentEnv: process.env.NODE_ENV ?? 'development',
820
- });
821
- if (!res.headersSent) {
822
- res.status(404).json({ error: 'Session not found' });
823
- }
824
- return;
825
- }
826
- log.warn('Hosted demo runtime rehydration failed for try session', error);
827
- if (!res.headersSent) {
828
- res.status(503).json({
829
- error: 'Demo session runtime unavailable',
830
- });
831
- }
832
- return;
833
- }
834
- const target = demoSessionService.getSessionProxyTarget(sessionId);
835
- if (!target) {
836
- demoAuthSessionService?.clearActiveDemoSessionIdForRequest(req, res);
837
- telemetry?.trackTryoutProxySessionMissing({
838
- demoSessionId: sessionId,
839
- deploymentEnv: process.env.NODE_ENV ?? 'development',
840
- });
841
- if (!res.headersSent) {
842
- res.status(404).json({ error: 'Session not found' });
843
- }
844
- return;
845
- }
846
- if ((0, shouldRecordHostedDemoSessionAction_1.shouldRecordHostedDemoSessionAction)(req)) {
847
- try {
848
- await demoSessionService.recordSessionAction(sessionId);
849
- }
850
- catch (error) {
851
- log.warn('Failed to persist hosted demo session action timestamp', error);
852
- }
853
- }
854
- mountedTrySessionProxy(req, res, next);
855
- })();
856
- });
857
- }
858
511
  app.use('/api', (0, support_1.createSupportRouter)(telemetry));
859
512
  // Static routes (only for static projects)
860
513
  if (staticService) {
@@ -881,46 +534,16 @@ const startServer = async (options) => {
881
534
  });
882
535
  app.get('/api/feature-flags', async (req, res) => {
883
536
  const configManager = (0, ConfigManager_1.getConfigManager)();
884
- const demoSessionId = res.locals.demoAuthSessionId;
885
- const demoAuth = demoAuthSessionService?.getAuthForSessionId(demoSessionId ?? '');
886
- const fallbackEmail = demoAuthSessionService
887
- ? demoAuth?.email
888
- : configManager.getEmail();
889
537
  const featureFlagUserKey = (0, featureFlagUserKey_1.getConfigFeatureFlagUserKey)({
890
538
  headers: req.headers,
891
- fallbackEmail,
539
+ fallbackEmail: configManager.getEmail(),
892
540
  });
893
541
  const featureFlags = await (0, evaluateFlags_1.getFeatureFlags)({ userKey: featureFlagUserKey });
894
542
  res.json({ featureFlags });
895
543
  });
896
544
  // Config endpoint
897
- app.get('/api/config', async (req, res) => {
545
+ app.get('/api/config', async (_req, res) => {
898
546
  const configManager = (0, ConfigManager_1.getConfigManager)();
899
- const demoSessionId = res.locals.demoAuthSessionId;
900
- const demoAuth = demoAuthSessionService?.getAuthForSessionId(demoSessionId ?? '');
901
- const isAuthenticatedInDemoMode = Boolean(demoAuth?.token);
902
- const isAuthenticated = demoAuthSessionService
903
- ? isAuthenticatedInDemoMode
904
- : configManager.isAuthenticated();
905
- const email = demoAuthSessionService
906
- ? demoAuth?.email
907
- : configManager.getEmail();
908
- const userId = demoAuthSessionService
909
- ? demoAuth?.userId
910
- : configManager.getUserId();
911
- // Display name lives in the access token's user_metadata (Google OAuth).
912
- // Decode the demo session's token directly; otherwise let ConfigManager
913
- // read it off the locally stored token. May be undefined (email-only
914
- // logins) — the UI falls back to email-derived initials.
915
- const name = demoAuthSessionService
916
- ? demoAuth?.token
917
- ? ((0, accessTokenRefresh_1.getJwtDisplayName)(demoAuth.token) ?? undefined)
918
- : undefined
919
- : configManager.getDisplayName();
920
- const activeDemoSessionId = demoAuth?.activeDemoSessionId ?? null;
921
- const activeSession = activeDemoSessionId
922
- ? demoSessionService?.getSession(activeDemoSessionId)
923
- : null;
924
547
  const desktopVersionPolicy = await (0, DesktopVersionPolicyService_1.getDesktopVersionPolicyService)().getPolicy();
925
548
  // In the zero-to-one flow the outer `projectPath` arg points at the
926
549
  // generated subproject (`<workspaceRoot>/.rivet/<slug>/`), but the
@@ -928,74 +551,31 @@ const startServer = async (options) => {
928
551
  // `.rivet/variants/` and per-project comments live. Prefer the bridge's
929
552
  // view so the UI's projectPathAtom resolves to the directory that owns
930
553
  // shared state, not the subproject of a single session.
931
- const livePath = activeSession?.projectPath ??
932
- sessionBridge?.getProjectPath() ??
933
- projectPath;
554
+ const livePath = sessionBridge?.getProjectPath() ?? projectPath;
934
555
  res.json({
935
- agentModeAvailable: isAuthenticated,
936
- email,
937
- userId,
938
- name,
939
- activeDemoSessionId,
556
+ agentModeAvailable: configManager.isAuthenticated(),
557
+ email: configManager.getEmail(),
558
+ userId: configManager.getUserId(),
559
+ name: configManager.getDisplayName(),
940
560
  isMCPSession: sessionBridge?.isActive() ?? false,
941
561
  mcpEditor: mcpEditor ?? null,
942
562
  agentApplyMode: sessionBridge?.isActive()
943
563
  ? (agentApplyMode ?? 'external')
944
564
  : null,
945
565
  projectPath: livePath,
946
- demoMode: isDemoModeEnabled,
947
566
  desktopVersionPolicy,
948
567
  });
949
568
  });
950
569
  // Store auth credentials after browser-based OAuth completion.
951
- // Hosted demo mode stores auth by browser session; non-demo keeps local config behavior.
952
570
  app.post('/api/auth/store', (req, res) => {
953
571
  const { email, token, refreshToken, userId } = req.body ?? {};
954
572
  if (!email || !token) {
955
- if (demoAuthSessionService) {
956
- telemetry?.trackTryoutAuthStoreFailed({
957
- reason: 'missing_email_or_token',
958
- statusCode: 400,
959
- deploymentEnv: process.env.NODE_ENV ?? 'development',
960
- });
961
- }
962
573
  return res.status(400).json({ error: 'Missing email or token' });
963
574
  }
964
575
  try {
965
- if (demoAuthSessionService) {
966
- const sessionId = res.locals.demoAuthSessionId;
967
- const demoSessionId = sessionId
968
- ? demoAuthSessionService.storeAuthForSessionId(sessionId, res, {
969
- token,
970
- email,
971
- refreshToken,
972
- userId,
973
- })
974
- : demoAuthSessionService.storeAuthForRequest(req, res, {
975
- token,
976
- email,
977
- refreshToken,
978
- userId,
979
- });
980
- telemetry?.trackTryoutAuthStoreCompleted({
981
- demoSessionId,
982
- hasRefreshToken: Boolean(refreshToken),
983
- deploymentEnv: process.env.NODE_ENV ?? 'development',
984
- });
985
- }
986
- else {
987
- const configManager = (0, ConfigManager_1.getConfigManager)();
988
- configManager.setAuth(token, email, refreshToken, userId);
989
- }
576
+ (0, ConfigManager_1.getConfigManager)().setAuth(token, email, refreshToken, userId);
990
577
  }
991
- catch (error) {
992
- if (demoAuthSessionService) {
993
- telemetry?.trackTryoutAuthStoreFailed({
994
- reason: error instanceof Error ? error.message : 'auth_store_failed',
995
- statusCode: 500,
996
- deploymentEnv: process.env.NODE_ENV ?? 'development',
997
- });
998
- }
578
+ catch {
999
579
  return res
1000
580
  .status(500)
1001
581
  .json({ error: 'Failed to store auth credentials' });
@@ -1004,14 +584,9 @@ const startServer = async (options) => {
1004
584
  log.info(`Stored auth for ${email} via browser OAuth`);
1005
585
  res.json({ success: true });
1006
586
  });
1007
- app.post('/api/auth/logout', (req, res) => {
587
+ app.post('/api/auth/logout', (_req, res) => {
1008
588
  try {
1009
- if (demoAuthSessionService) {
1010
- demoAuthSessionService.clearAuthForRequest(req, res);
1011
- }
1012
- else {
1013
- (0, ConfigManager_1.getConfigManager)().clearAuth();
1014
- }
589
+ (0, ConfigManager_1.getConfigManager)().clearAuth();
1015
590
  }
1016
591
  catch (error) {
1017
592
  log.warn('Logout failed', error);
@@ -1117,15 +692,11 @@ const startServer = async (options) => {
1117
692
  // Start server
1118
693
  const activeSockets = new Set();
1119
694
  // Advertise this server for CLI attach (`rivet status`, `rivet open`, …).
1120
- // Hosted demo orchestrators are multi-session and never CLI-attached.
1121
695
  let handshakeApplyMode = 'none';
1122
696
  if (sessionBridge) {
1123
697
  handshakeApplyMode = agentApplyMode === 'embedded' ? 'embedded' : 'none';
1124
698
  }
1125
699
  const advertiseCliHandshake = () => {
1126
- if (isDemoModeEnabled) {
1127
- return;
1128
- }
1129
700
  try {
1130
701
  (0, serverHandshake_1.writeHandshake)({
1131
702
  version: serverHandshake_1.CLI_HANDSHAKE_VERSION,
@@ -1144,9 +715,6 @@ const startServer = async (options) => {
1144
715
  }
1145
716
  };
1146
717
  const retireCliHandshake = () => {
1147
- if (isDemoModeEnabled) {
1148
- return;
1149
- }
1150
718
  (0, serverHandshake_1.removeHandshake)(projectPath, process.pid);
1151
719
  };
1152
720
  const httpServer = await new Promise((resolve, reject) => {
@@ -1176,44 +744,6 @@ const startServer = async (options) => {
1176
744
  server.on('upgrade', (req, socket, head) => {
1177
745
  const pathname = req.url?.split('?')[0] ?? '';
1178
746
  log.debug(`WebSocket upgrade request for: ${pathname}`);
1179
- const trySessionMatch = /^\/try\/([^/]+)/.exec(pathname);
1180
- if (trySessionMatch && trySessionProxy?.upgrade && demoSessionService) {
1181
- const sessionId = trySessionMatch[1];
1182
- void (async () => {
1183
- try {
1184
- await demoSessionService.ensureRuntimeReady(sessionId);
1185
- }
1186
- catch {
1187
- socket.destroy();
1188
- return;
1189
- }
1190
- const target = demoSessionService.getSessionProxyTarget(sessionId);
1191
- if (!target) {
1192
- socket.destroy();
1193
- return;
1194
- }
1195
- if (requiresDemoAuth) {
1196
- const auth = demoAuthSessionService?.getAuthForRequest(req);
1197
- if (!auth?.token) {
1198
- log.debug('Rejecting unauthenticated hosted demo upgrade request');
1199
- socket.destroy();
1200
- return;
1201
- }
1202
- const sessionOwnerUserId = demoSessionService.getSessionOwnerUserId(sessionId);
1203
- const requestOwnerUserId = auth.email?.trim().toLowerCase() ?? null;
1204
- if (sessionOwnerUserId &&
1205
- requestOwnerUserId &&
1206
- sessionOwnerUserId !== requestOwnerUserId) {
1207
- log.debug('Rejecting non-owner hosted demo upgrade request');
1208
- socket.destroy();
1209
- return;
1210
- }
1211
- }
1212
- log.debug('Proxying upgrade to hosted demo session for HMR');
1213
- trySessionProxy.upgrade(req, socket, head);
1214
- })();
1215
- return;
1216
- }
1217
747
  // Proxy to user's dev server for HMR
1218
748
  const proxyUpgrade = userDevProxy?.middleware?.upgrade;
1219
749
  if ((framework !== 'static' || hasUserDevServer) && proxyUpgrade) {
@@ -1271,10 +801,6 @@ const startServer = async (options) => {
1271
801
  return;
1272
802
  }
1273
803
  void (async () => {
1274
- if (demoSessionService) {
1275
- await demoSessionService.shutdown();
1276
- }
1277
- demoAuthSessionService?.shutdown();
1278
804
  await (0, exports.runServerShutdownTasks)({
1279
805
  beforeShutdown: options.beforeShutdown,
1280
806
  telemetry,