@standardagents/builder 0.17.3 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/plugin.js CHANGED
@@ -7206,6 +7206,7 @@ const PUBLIC_ROUTES = [
7206
7206
  '/api/auth/bootstrap',
7207
7207
  '/api/auth/login',
7208
7208
  '/api/auth/config',
7209
+ '/api/auth/platform-replica',
7209
7210
  '/api/auth/sa/start', // Login with Standard Agents (OAuth) \u2014 unauthenticated entry
7210
7211
  '/api/auth/sa/callback', // OAuth callback (sets the session cookie)
7211
7212
  '/api/config',
@@ -7253,16 +7254,25 @@ function isPublicRoute(routePath, hosted) {
7253
7254
  return true;
7254
7255
  }
7255
7256
 
7256
- // Platform proxy routes handle their own auth.
7257
+ // Platform proxy routes handle their own auth in local dev only.
7258
+ if (hosted && (routePath.startsWith('/api/platform/') || routePath === '/api/platform')) {
7259
+ return false;
7260
+ }
7257
7261
  if (routePath.startsWith('/api/platform/') || routePath === '/api/platform') {
7258
7262
  return true;
7259
7263
  }
7260
7264
 
7261
- // Platform session proxy and auth bridge handle auth via platform cookies.
7265
+ // Platform session proxy and auth bridge are local-dev helpers only.
7266
+ if (hosted && (routePath.startsWith('/api/platform-session/') || routePath === '/api/platform-session')) {
7267
+ return false;
7268
+ }
7262
7269
  if (routePath.startsWith('/api/platform-session/') || routePath === '/api/platform-session') {
7263
7270
  return true;
7264
7271
  }
7265
7272
 
7273
+ if (hosted && (routePath.startsWith('/api/platform-auth/') || routePath === '/api/platform-auth')) {
7274
+ return false;
7275
+ }
7266
7276
  if (routePath.startsWith('/api/platform-auth/') || routePath === '/api/platform-auth') {
7267
7277
  return true;
7268
7278
  }
@@ -7270,6 +7280,36 @@ function isPublicRoute(routePath, hosted) {
7270
7280
  return false;
7271
7281
  }
7272
7282
 
7283
+ function platformEndpoint(env) {
7284
+ const configured =
7285
+ env && (env.PLATFORM_ENDPOINT || env.STANDARD_AGENTS_PLATFORM_URL || env.PLATFORM_URL || env.STANDARD_AGENTS_PUBLIC_URL);
7286
+ if (typeof configured === 'string' && configured.trim()) {
7287
+ return configured.trim().replace(/\\/+$/, '');
7288
+ }
7289
+ return 'https://platform.standardagents.ai';
7290
+ }
7291
+
7292
+ function hostedInstanceRedirectId(request, env) {
7293
+ const configured = env && (env.STANDARD_AGENTS_PROJECT_ID || env.STANDARD_AGENTS_INSTANCE_ID || env.STANDARD_AGENTS_INSTANCE_SUBDOMAIN);
7294
+ if (typeof configured === 'string' && configured.trim()) {
7295
+ return configured.trim();
7296
+ }
7297
+ return new URL(request.url).hostname;
7298
+ }
7299
+
7300
+ function platformLoginUrl(request, env) {
7301
+ const requestUrl = new URL(request.url);
7302
+ const url = new URL('/login', platformEndpoint(env));
7303
+ url.searchParams.set('redirect', hostedInstanceRedirectId(request, env));
7304
+ url.searchParams.set('return_to', requestUrl.pathname + requestUrl.search || '/');
7305
+ return url.toString();
7306
+ }
7307
+
7308
+ function isHtmlNavigationRequest(request) {
7309
+ if (request.method !== 'GET' && request.method !== 'HEAD') return false;
7310
+ return (request.headers.get('Accept') || '').includes('text/html');
7311
+ }
7312
+
7273
7313
  // CORS headers for API responses
7274
7314
  const CORS_HEADERS = {
7275
7315
  "Access-Control-Allow-Origin": "*",
@@ -7361,6 +7401,21 @@ ${packedThreadRouteCode}
7361
7401
  }
7362
7402
 
7363
7403
  authContext = authResult;
7404
+
7405
+ if (routePath.startsWith('/api/threads/')) {
7406
+ const threadId = routeMatch.params?.id || routeMatch.params?.threadId;
7407
+ if (threadId) {
7408
+ const agentBuilderId = env.AGENT_BUILDER.idFromName('singleton');
7409
+ const agentBuilder = env.AGENT_BUILDER.get(agentBuilderId);
7410
+ const thread = await agentBuilder.getThread(threadId);
7411
+ if (!thread) {
7412
+ return addCorsHeaders(Response.json({ error: \`Thread not found: \${threadId}\` }, { status: 404 }));
7413
+ }
7414
+ if (authContext.user.role !== 'admin' && (thread.user_id === null || thread.user_id !== authContext.user.id)) {
7415
+ return addCorsHeaders(Response.json({ error: "Forbidden: You don't have access to this thread" }, { status: 403 }));
7416
+ }
7417
+ }
7418
+ }
7364
7419
  }
7365
7420
 
7366
7421
  let controller = await routeMatch.data();
@@ -7396,6 +7451,19 @@ ${packedThreadRouteCode}
7396
7451
  });
7397
7452
  }
7398
7453
 
7454
+ // Hosted browser navigations do not render a local login page. Redirect
7455
+ // anonymous users directly to the platform, where the instance membership is
7456
+ // resolved and returned as a signed handoff token.
7457
+ if (isHostedInstance(env) && isHtmlNavigationRequest(request)) {
7458
+ const authResult = await requireAuth(request, env);
7459
+ if (authResult instanceof Response) {
7460
+ return new Response(null, {
7461
+ status: 302,
7462
+ headers: { Location: platformLoginUrl(request, env) },
7463
+ });
7464
+ }
7465
+ }
7466
+
7399
7467
  // Serve UI for all other routes (SPA fallback)
7400
7468
  return serveUI(routePath, env);
7401
7469
  }