@standardagents/builder 0.17.2 → 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.
@@ -3672,13 +3672,13 @@ var init_ToolExecutor = __esm({
3672
3672
  };
3673
3673
  }
3674
3674
  const reader = result.stream.getReader();
3675
- const decoder = new TextDecoder();
3675
+ const decoder2 = new TextDecoder();
3676
3676
  let textContent = "";
3677
3677
  try {
3678
3678
  while (true) {
3679
3679
  const { done, value } = await reader.read();
3680
3680
  if (done) break;
3681
- textContent += decoder.decode(value, { stream: true });
3681
+ textContent += decoder2.decode(value, { stream: true });
3682
3682
  }
3683
3683
  } finally {
3684
3684
  reader.releaseLock();
@@ -11628,8 +11628,8 @@ var init_ThreadStateImpl = __esm({
11628
11628
  } else {
11629
11629
  let base64Data;
11630
11630
  if (typeof data === "string") {
11631
- const encoder = new TextEncoder();
11632
- const bytes = encoder.encode(data);
11631
+ const encoder2 = new TextEncoder();
11632
+ const bytes = encoder2.encode(data);
11633
11633
  let binary = "";
11634
11634
  for (let i = 0; i < bytes.length; i++) {
11635
11635
  binary += String.fromCharCode(bytes[i]);
@@ -13703,12 +13703,12 @@ function parseToolArguments(argumentsJson) {
13703
13703
  }
13704
13704
  async function* parseChatSSEStream(stream, state) {
13705
13705
  const reader = stream.getReader();
13706
- const decoder = new TextDecoder();
13706
+ const decoder2 = new TextDecoder();
13707
13707
  let buffer = "";
13708
13708
  while (true) {
13709
13709
  const { value, done } = await reader.read();
13710
13710
  if (done) break;
13711
- buffer += decoder.decode(value, { stream: true });
13711
+ buffer += decoder2.decode(value, { stream: true });
13712
13712
  while (true) {
13713
13713
  const separatorIndex = buffer.indexOf("\n\n");
13714
13714
  if (separatorIndex === -1) break;
@@ -15086,13 +15086,13 @@ async function* parseChatSSEStream2(response, state) {
15086
15086
  if (!reader) {
15087
15087
  throw new Error("No response body");
15088
15088
  }
15089
- const decoder = new TextDecoder();
15089
+ const decoder2 = new TextDecoder();
15090
15090
  let buffer = "";
15091
15091
  try {
15092
15092
  while (true) {
15093
15093
  const { done, value } = await reader.read();
15094
15094
  if (done) break;
15095
- buffer += decoder.decode(value, { stream: true });
15095
+ buffer += decoder2.decode(value, { stream: true });
15096
15096
  const lines = buffer.split("\n");
15097
15097
  buffer = lines.pop() || "";
15098
15098
  for (const line of lines) {
@@ -25381,12 +25381,12 @@ function concatBytes(buffers) {
25381
25381
  return output;
25382
25382
  }
25383
25383
  function encodeUTF8(str) {
25384
- let encoder;
25385
- return (encodeUTF8_ !== null && encodeUTF8_ !== void 0 ? encodeUTF8_ : (encoder = new globalThis.TextEncoder(), encodeUTF8_ = encoder.encode.bind(encoder)))(str);
25384
+ let encoder2;
25385
+ return (encodeUTF8_ !== null && encodeUTF8_ !== void 0 ? encodeUTF8_ : (encoder2 = new globalThis.TextEncoder(), encodeUTF8_ = encoder2.encode.bind(encoder2)))(str);
25386
25386
  }
25387
25387
  function decodeUTF8(bytes) {
25388
- let decoder;
25389
- return (decodeUTF8_ !== null && decodeUTF8_ !== void 0 ? decodeUTF8_ : (decoder = new globalThis.TextDecoder(), decodeUTF8_ = decoder.decode.bind(decoder)))(bytes);
25388
+ let decoder2;
25389
+ return (decodeUTF8_ !== null && decodeUTF8_ !== void 0 ? decodeUTF8_ : (decoder2 = new globalThis.TextDecoder(), decodeUTF8_ = decoder2.decode.bind(decoder2)))(bytes);
25390
25390
  }
25391
25391
  function findNewlineIndex(buffer, startIndex) {
25392
25392
  const newline = 10;
@@ -29093,7 +29093,7 @@ var init_web = __esm({
29093
29093
  return __asyncGenerator(this, arguments, function* processStreamResponse_1() {
29094
29094
  var _a16;
29095
29095
  const reader = (_a16 = response === null || response === void 0 ? void 0 : response.body) === null || _a16 === void 0 ? void 0 : _a16.getReader();
29096
- const decoder = new TextDecoder("utf-8");
29096
+ const decoder2 = new TextDecoder("utf-8");
29097
29097
  if (!reader) {
29098
29098
  throw new Error("Response body is empty");
29099
29099
  }
@@ -29109,7 +29109,7 @@ var init_web = __esm({
29109
29109
  }
29110
29110
  break;
29111
29111
  }
29112
- const chunkString = decoder.decode(value, { stream: true });
29112
+ const chunkString = decoder2.decode(value, { stream: true });
29113
29113
  try {
29114
29114
  const chunkJson = JSON.parse(chunkString);
29115
29115
  if ("error" in chunkJson) {
@@ -35732,12 +35732,12 @@ function concatBytes2(buffers) {
35732
35732
  return output;
35733
35733
  }
35734
35734
  function encodeUTF82(str) {
35735
- let encoder;
35736
- return (encodeUTF8_2 ?? (encoder = new globalThis.TextEncoder(), encodeUTF8_2 = encoder.encode.bind(encoder)))(str);
35735
+ let encoder2;
35736
+ return (encodeUTF8_2 ?? (encoder2 = new globalThis.TextEncoder(), encodeUTF8_2 = encoder2.encode.bind(encoder2)))(str);
35737
35737
  }
35738
35738
  function decodeUTF82(bytes) {
35739
- let decoder;
35740
- return (decodeUTF8_2 ?? (decoder = new globalThis.TextDecoder(), decodeUTF8_2 = decoder.decode.bind(decoder)))(bytes);
35739
+ let decoder2;
35740
+ return (decodeUTF8_2 ?? (decoder2 = new globalThis.TextDecoder(), decodeUTF8_2 = decoder2.decode.bind(decoder2)))(bytes);
35741
35741
  }
35742
35742
  var encodeUTF8_2, decodeUTF8_2;
35743
35743
  var init_bytes = __esm({
@@ -50030,8 +50030,8 @@ async function oAuthCreateSHA256CodeChallenge(params = {}) {
50030
50030
  };
50031
50031
  }
50032
50032
  const { codeVerifier = generateCodeVerifier() } = parsedParams.data;
50033
- const encoder = new TextEncoder();
50034
- const data = encoder.encode(codeVerifier);
50033
+ const encoder2 = new TextEncoder();
50034
+ const data = encoder2.encode(codeVerifier);
50035
50035
  const hash = await crypto.subtle.digest("SHA-256", data);
50036
50036
  const hashArray = new Uint8Array(hash);
50037
50037
  const codeChallenge = arrayBufferToBase64Url(hashArray);
@@ -51840,13 +51840,13 @@ async function* parseChatSSEStream3(response, state) {
51840
51840
  if (!reader) {
51841
51841
  throw new Error("No response body");
51842
51842
  }
51843
- const decoder = new TextDecoder();
51843
+ const decoder2 = new TextDecoder();
51844
51844
  let buffer = "";
51845
51845
  try {
51846
51846
  while (true) {
51847
51847
  const { done, value } = await reader.read();
51848
51848
  if (done) break;
51849
- buffer += decoder.decode(value, { stream: true });
51849
+ buffer += decoder2.decode(value, { stream: true });
51850
51850
  const lines = buffer.split("\n");
51851
51851
  buffer = lines.pop() || "";
51852
51852
  for (const line of lines) {
@@ -52782,13 +52782,13 @@ async function* parseSSEStream(response, state) {
52782
52782
  if (!reader) {
52783
52783
  throw new Error("No response body");
52784
52784
  }
52785
- const decoder = new TextDecoder();
52785
+ const decoder2 = new TextDecoder();
52786
52786
  let buffer = "";
52787
52787
  try {
52788
52788
  while (true) {
52789
52789
  const { done, value } = await reader.read();
52790
52790
  if (done) break;
52791
- buffer += decoder.decode(value, { stream: true });
52791
+ buffer += decoder2.decode(value, { stream: true });
52792
52792
  const lines = buffer.split("\n");
52793
52793
  buffer = lines.pop() || "";
52794
52794
  for (const line of lines) {
@@ -63020,8 +63020,8 @@ function generateApiKey() {
63020
63020
  return `agtbldr_${generateSecureToken(32)}`;
63021
63021
  }
63022
63022
  async function hashPassword(password) {
63023
- const encoder = new TextEncoder();
63024
- const data = encoder.encode(password);
63023
+ const encoder2 = new TextEncoder();
63024
+ const data = encoder2.encode(password);
63025
63025
  const salt = crypto.getRandomValues(new Uint8Array(16));
63026
63026
  const keyMaterial = await crypto.subtle.importKey(
63027
63027
  "raw",
@@ -63051,8 +63051,8 @@ async function verifyPassword(password, hash) {
63051
63051
  const combined = base64ToBuffer(hash);
63052
63052
  const salt = combined.slice(0, 16);
63053
63053
  const storedHash = combined.slice(16);
63054
- const encoder = new TextEncoder();
63055
- const data = encoder.encode(password);
63054
+ const encoder2 = new TextEncoder();
63055
+ const data = encoder2.encode(password);
63056
63056
  const keyMaterial = await crypto.subtle.importKey(
63057
63057
  "raw",
63058
63058
  data,
@@ -63087,8 +63087,8 @@ async function verifyPassword(password, hash) {
63087
63087
  }
63088
63088
  }
63089
63089
  async function hashToken(token) {
63090
- const encoder = new TextEncoder();
63091
- const data = encoder.encode(token);
63090
+ const encoder2 = new TextEncoder();
63091
+ const data = encoder2.encode(token);
63092
63092
  const hashBuffer = await crypto.subtle.digest("SHA-256", data);
63093
63093
  const hashArray = new Uint8Array(hashBuffer);
63094
63094
  return Array.from(hashArray, (byte) => byte.toString(16).padStart(2, "0")).join("");
@@ -63100,15 +63100,39 @@ function getTokenPrefix(token) {
63100
63100
  const match2 = token.match(/^([^_]+_)/);
63101
63101
  return match2 ? match2[1] : "";
63102
63102
  }
63103
+ var SESSION_COOKIE_NAME = "agtuser_session";
63104
+ function readSessionCookie(request) {
63105
+ const header = request.headers.get("Cookie");
63106
+ if (!header) return null;
63107
+ for (const part of header.split(";")) {
63108
+ const eq = part.indexOf("=");
63109
+ if (eq === -1) continue;
63110
+ if (part.slice(0, eq).trim() === SESSION_COOKIE_NAME) {
63111
+ return decodeURIComponent(part.slice(eq + 1).trim()) || null;
63112
+ }
63113
+ }
63114
+ return null;
63115
+ }
63116
+ function buildSessionCookie(request, token, maxAgeSeconds) {
63117
+ const attrs = ["Path=/", "HttpOnly", "SameSite=Lax"];
63118
+ try {
63119
+ if (new URL(request.url).protocol === "https:") attrs.push("Secure");
63120
+ } catch {
63121
+ }
63122
+ if (maxAgeSeconds <= 0) {
63123
+ return `${SESSION_COOKIE_NAME}=; ${attrs.join("; ")}; Max-Age=0`;
63124
+ }
63125
+ return `${SESSION_COOKIE_NAME}=${encodeURIComponent(token)}; ${attrs.join("; ")}; Max-Age=${maxAgeSeconds}`;
63126
+ }
63103
63127
  function isValidUserToken(token) {
63104
63128
  return token.startsWith("agtuser_") && token.length > 10;
63105
63129
  }
63106
63130
  function isValidApiKey(key) {
63107
- return key.startsWith("agtbldr_") && key.length > 10;
63131
+ return key.startsWith("agtbldr_") && key.length > 10 || key.startsWith("sak_live_") && key.length > 10;
63108
63132
  }
63109
63133
  async function signToken(payload, encryptionKey) {
63110
- const encoder = new TextEncoder();
63111
- const keyData = encoder.encode(encryptionKey);
63134
+ const encoder2 = new TextEncoder();
63135
+ const keyData = encoder2.encode(encryptionKey);
63112
63136
  const cryptoKey = await crypto.subtle.importKey(
63113
63137
  "raw",
63114
63138
  keyData,
@@ -63116,7 +63140,7 @@ async function signToken(payload, encryptionKey) {
63116
63140
  false,
63117
63141
  ["sign"]
63118
63142
  );
63119
- const payloadData = encoder.encode(payload);
63143
+ const payloadData = encoder2.encode(payload);
63120
63144
  const signature = await crypto.subtle.sign("HMAC", cryptoKey, payloadData);
63121
63145
  const payloadB64 = bufferToBase64(new Uint8Array(payloadData));
63122
63146
  const signatureB64 = bufferToBase64(new Uint8Array(signature));
@@ -63129,8 +63153,8 @@ async function verifySignedToken(signedToken, encryptionKey) {
63129
63153
  return null;
63130
63154
  }
63131
63155
  const [payloadB64, signatureB64] = parts;
63132
- const encoder = new TextEncoder();
63133
- const keyData = encoder.encode(encryptionKey);
63156
+ const encoder2 = new TextEncoder();
63157
+ const keyData = encoder2.encode(encryptionKey);
63134
63158
  const cryptoKey = await crypto.subtle.importKey(
63135
63159
  "raw",
63136
63160
  keyData,
@@ -63144,8 +63168,8 @@ async function verifySignedToken(signedToken, encryptionKey) {
63144
63168
  if (!isValid) {
63145
63169
  return null;
63146
63170
  }
63147
- const decoder = new TextDecoder();
63148
- return decoder.decode(payloadData);
63171
+ const decoder2 = new TextDecoder();
63172
+ return decoder2.decode(payloadData);
63149
63173
  } catch (error) {
63150
63174
  console.error("Error verifying signed token:", error);
63151
63175
  return null;
@@ -63202,6 +63226,10 @@ function extractBearerToken(request) {
63202
63226
  if (authHeader && authHeader.startsWith("Bearer ")) {
63203
63227
  return authHeader.substring(7);
63204
63228
  }
63229
+ const cookieToken = readSessionCookie(request);
63230
+ if (cookieToken) {
63231
+ return cookieToken;
63232
+ }
63205
63233
  const isWebSocket = request.headers.get("upgrade")?.toLowerCase() === "websocket";
63206
63234
  if (isWebSocket) {
63207
63235
  try {
@@ -63253,7 +63281,11 @@ async function authenticate(request, env2) {
63253
63281
  user: {
63254
63282
  id: user.id,
63255
63283
  username: user.username,
63256
- role: user.role
63284
+ role: user.role,
63285
+ platform_user_id: user.platform_user_id ?? null,
63286
+ email: user.email ?? null,
63287
+ display_name: user.display_name ?? null,
63288
+ avatar_url: user.avatar_url ?? null
63257
63289
  },
63258
63290
  authType: "session"
63259
63291
  };
@@ -63271,7 +63303,11 @@ async function authenticate(request, env2) {
63271
63303
  user: {
63272
63304
  id: user.id,
63273
63305
  username: user.username,
63274
- role: user.role
63306
+ role: user.role,
63307
+ platform_user_id: user.platform_user_id ?? null,
63308
+ email: user.email ?? null,
63309
+ display_name: user.display_name ?? null,
63310
+ avatar_url: user.avatar_url ?? null
63275
63311
  },
63276
63312
  authType: "api_key"
63277
63313
  };
@@ -63307,88 +63343,6 @@ async function requireAdmin(request, env2) {
63307
63343
  return result;
63308
63344
  }
63309
63345
 
63310
- // src/api/api-keys/index.get.ts
63311
- var index_get_default = defineController2(async ({ req, env: env2 }) => {
63312
- try {
63313
- const authResult = await requireAuth(req, env2);
63314
- if (authResult instanceof Response) {
63315
- return authResult;
63316
- }
63317
- if (authResult.authType === "super_admin") {
63318
- return Response.json({ keys: [], message: "Super admin has no API keys. Create a user account to manage API keys." });
63319
- }
63320
- const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
63321
- const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
63322
- const keys = await agentBuilder.listApiKeys(authResult.user.id);
63323
- return Response.json({ keys });
63324
- } catch (error) {
63325
- console.error("List API keys error:", error);
63326
- return Response.json(
63327
- { error: error.message || "Failed to list API keys" },
63328
- { status: 500 }
63329
- );
63330
- }
63331
- });
63332
-
63333
- // src/api/api-keys/index.post.ts
63334
- var index_post_default2 = defineController2(async ({ req, env: env2 }) => {
63335
- try {
63336
- const authResult = await requireAuth(req, env2);
63337
- if (authResult instanceof Response) {
63338
- return authResult;
63339
- }
63340
- if (authResult.authType === "super_admin") {
63341
- return Response.json(
63342
- { error: "Super admin cannot create API keys. Please create a user account first." },
63343
- { status: 400 }
63344
- );
63345
- }
63346
- const body = await req.json();
63347
- const { name: name15 } = body;
63348
- if (!name15 || typeof name15 !== "string") {
63349
- return Response.json(
63350
- { error: "Name is required" },
63351
- { status: 400 }
63352
- );
63353
- }
63354
- if (name15.length < 1 || name15.length > 100) {
63355
- return Response.json(
63356
- { error: "Name must be between 1 and 100 characters" },
63357
- { status: 400 }
63358
- );
63359
- }
63360
- const apiKey = generateApiKey();
63361
- const keyHash = await hashToken(apiKey);
63362
- const keyPrefix = getTokenPrefix(apiKey);
63363
- const lastFive = getLastChars(apiKey, 5);
63364
- const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
63365
- const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
63366
- const id = await agentBuilder.createApiKey({
63367
- name: name15,
63368
- key_hash: keyHash,
63369
- key_prefix: keyPrefix,
63370
- last_five: lastFive,
63371
- user_id: authResult.user.id
63372
- });
63373
- const now = Math.floor(Date.now() / 1e3);
63374
- return Response.json({
63375
- key: apiKey,
63376
- // Only returned once on creation
63377
- id,
63378
- name: name15,
63379
- key_prefix: keyPrefix,
63380
- last_five: lastFive,
63381
- created_at: now
63382
- }, { status: 201 });
63383
- } catch (error) {
63384
- console.error("Create API key error:", error);
63385
- return Response.json(
63386
- { error: error.message || "Failed to create API key" },
63387
- { status: 500 }
63388
- );
63389
- }
63390
- });
63391
-
63392
63346
  // src/utils/platform-auth.ts
63393
63347
  var FALLBACK_PLATFORM_ORIGIN = "https://platform.standardagents.ai";
63394
63348
  var SESSION_TTL_SECONDS = 30 * 24 * 60 * 60;
@@ -63399,6 +63353,10 @@ function platformApiKey(env2) {
63399
63353
  function hasPlatformApiKey(env2) {
63400
63354
  return platformApiKey(env2) !== null;
63401
63355
  }
63356
+ function isPlatformHosted(env2) {
63357
+ const value = env2.STANDARD_AGENTS_HOSTED;
63358
+ return typeof value === "string" ? value.trim() !== "" && value.trim() !== "0" && value.trim().toLowerCase() !== "false" : Boolean(value);
63359
+ }
63402
63360
  function platformEndpoint(env2) {
63403
63361
  const configured = env2.PLATFORM_ENDPOINT || env2.STANDARD_AGENTS_PLATFORM_URL || env2.PLATFORM_URL || env2.STANDARD_AGENTS_PUBLIC_URL;
63404
63362
  if (typeof configured === "string" && configured.trim()) {
@@ -63406,21 +63364,25 @@ function platformEndpoint(env2) {
63406
63364
  }
63407
63365
  return FALLBACK_PLATFORM_ORIGIN;
63408
63366
  }
63367
+ function hostedInstanceRedirectId(req, env2) {
63368
+ const configured = env2.STANDARD_AGENTS_PROJECT_ID || env2.STANDARD_AGENTS_INSTANCE_ID || env2.STANDARD_AGENTS_INSTANCE_SUBDOMAIN;
63369
+ if (typeof configured === "string" && configured.trim()) {
63370
+ return configured.trim();
63371
+ }
63372
+ return new URL(req.url).hostname;
63373
+ }
63374
+ function platformLoginUrl(req, env2, returnTo) {
63375
+ const url = new URL("/login", platformEndpoint(env2));
63376
+ url.searchParams.set("redirect", hostedInstanceRedirectId(req, env2));
63377
+ const reqUrl = new URL(req.url);
63378
+ const next = returnTo && returnTo.startsWith("/") && !returnTo.startsWith("//") ? returnTo : `${reqUrl.pathname}${reqUrl.search}`;
63379
+ url.searchParams.set("return_to", next || "/");
63380
+ return url.toString();
63381
+ }
63409
63382
  function sanitizeUsername(input) {
63410
63383
  const normalized = input.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 50);
63411
63384
  return normalized || "standard-agents";
63412
63385
  }
63413
- async function fallbackAccountForToken(token) {
63414
- const tokenHash = await hashToken(token);
63415
- const suffix = tokenHash.slice(0, 12);
63416
- return {
63417
- id: `platform-token-${suffix}`,
63418
- name: "Standard Agents",
63419
- slug: `standard-agents-${suffix}`,
63420
- tier: void 0,
63421
- status: "token-present"
63422
- };
63423
- }
63424
63386
  function normalizeAccount(payload) {
63425
63387
  const account = payload.account;
63426
63388
  if (!account) return null;
@@ -63454,21 +63416,70 @@ async function fetchPlatformAccount(endpoint, token) {
63454
63416
  return null;
63455
63417
  }
63456
63418
  }
63419
+ function normalizeLocalBootstrap(payload, endpoint) {
63420
+ const projectId = typeof payload.project?.id === "string" ? payload.project.id : null;
63421
+ const platformUserId = typeof payload.user?.platform_user_id === "string" ? payload.user.platform_user_id : typeof payload.user?.id === "string" ? payload.user.id : null;
63422
+ const role = payload.user?.role === "user" ? "user" : payload.user?.role === "admin" ? "admin" : null;
63423
+ if (!projectId || !platformUserId || !role) return null;
63424
+ const username = typeof payload.user?.username === "string" && payload.user.username.trim() ? sanitizeUsername(payload.user.username) : sanitizeUsername(
63425
+ typeof payload.user?.email === "string" && payload.user.email.includes("@") ? payload.user.email.split("@")[0] : `sa-${platformUserId.slice(0, 12)}`
63426
+ );
63427
+ const accountId = typeof payload.project?.account_id === "string" ? payload.project.account_id : projectId;
63428
+ const accountSlug = typeof payload.project?.subdomain === "string" && payload.project.subdomain.trim() ? payload.project.subdomain.trim() : projectId;
63429
+ return {
63430
+ connected: true,
63431
+ verified: true,
63432
+ account: {
63433
+ id: accountId,
63434
+ name: accountSlug,
63435
+ slug: accountSlug,
63436
+ status: "active"
63437
+ },
63438
+ user: {
63439
+ id: platformUserId,
63440
+ username,
63441
+ role,
63442
+ email: typeof payload.user?.email === "string" ? payload.user.email : null,
63443
+ display_name: typeof payload.user?.display_name === "string" ? payload.user.display_name : null,
63444
+ avatar_url: typeof payload.user?.avatar_url === "string" ? payload.user.avatar_url : null,
63445
+ source: "standard_agents"
63446
+ },
63447
+ platformEndpoint: endpoint
63448
+ };
63449
+ }
63450
+ async function fetchLocalBootstrapIdentity(endpoint, token) {
63451
+ const response = await fetch(`${endpoint}/auth/local-bootstrap`, {
63452
+ headers: {
63453
+ Authorization: `Bearer ${token}`
63454
+ }
63455
+ });
63456
+ if (!response.ok) {
63457
+ return null;
63458
+ }
63459
+ const data = await response.json().catch(() => null);
63460
+ return data ? normalizeLocalBootstrap(data, endpoint) : null;
63461
+ }
63457
63462
  async function getPlatformIdentity(env2) {
63458
63463
  const token = platformApiKey(env2);
63459
63464
  if (!token) {
63460
63465
  return null;
63461
63466
  }
63462
63467
  const endpoint = platformEndpoint(env2);
63468
+ const bootstrapIdentity = await fetchLocalBootstrapIdentity(endpoint, token).catch(() => null);
63469
+ if (bootstrapIdentity) {
63470
+ return bootstrapIdentity;
63471
+ }
63463
63472
  const verifiedAccount = await fetchPlatformAccount(endpoint, token);
63464
- const account = verifiedAccount ?? await fallbackAccountForToken(token);
63465
- const username = sanitizeUsername(account.slug);
63473
+ if (!verifiedAccount) {
63474
+ return null;
63475
+ }
63476
+ const username = sanitizeUsername(verifiedAccount.slug);
63466
63477
  return {
63467
63478
  connected: true,
63468
63479
  verified: verifiedAccount !== null,
63469
- account,
63480
+ account: verifiedAccount,
63470
63481
  user: {
63471
- id: account.id,
63482
+ id: verifiedAccount.id,
63472
63483
  username,
63473
63484
  role: "admin",
63474
63485
  source: "standard_agents"
@@ -63476,32 +63487,54 @@ async function getPlatformIdentity(env2) {
63476
63487
  platformEndpoint: endpoint
63477
63488
  };
63478
63489
  }
63490
+ async function mintLocalSessionForPlatformUser(env2, platformUser) {
63491
+ const namespace = env2.AGENT_BUILDER;
63492
+ if (!namespace || typeof namespace.idFromName !== "function" || typeof namespace.get !== "function") {
63493
+ throw new Error("Server misconfigured: AGENT_BUILDER Durable Object binding is required for platform auth");
63494
+ }
63495
+ const agentBuilder = namespace.get(namespace.idFromName("singleton"));
63496
+ const profile = typeof platformUser === "string" ? { platform_user_id: platformUser, username: `sa-${platformUser.slice(0, 12)}`, role: "admin" } : platformUser;
63497
+ const user = await agentBuilder.upsertPlatformReplicaUser({
63498
+ platform_user_id: profile.platform_user_id,
63499
+ username: profile.username ?? null,
63500
+ display_name: profile.display_name ?? null,
63501
+ email: profile.email ?? null,
63502
+ avatar_url: profile.avatar_url ?? null,
63503
+ role: profile.role ?? "admin"
63504
+ });
63505
+ const token = generateUserToken();
63506
+ const tokenHash = await hashToken(token);
63507
+ const expiresAt = Math.floor(Date.now() / 1e3) + SESSION_TTL_SECONDS;
63508
+ await agentBuilder.createSession({ user_id: user.id, token_hash: tokenHash, expires_at: expiresAt });
63509
+ return { token, user: { id: user.id, username: user.username, role: user.role } };
63510
+ }
63479
63511
  async function createPlatformLocalSession(env2) {
63480
- const identity = await getPlatformIdentity(env2);
63481
- if (!identity) {
63512
+ if (isPlatformHosted(env2)) {
63513
+ return null;
63514
+ }
63515
+ const apiKey = platformApiKey(env2);
63516
+ if (!apiKey) {
63482
63517
  return null;
63483
63518
  }
63519
+ const endpoint = platformEndpoint(env2);
63520
+ const identity = await fetchLocalBootstrapIdentity(endpoint, apiKey).catch(() => null);
63521
+ if (!identity) {
63522
+ throw new Error("STANDARD_AGENTS_API_KEY could not be resolved to one active user-instance membership.");
63523
+ }
63484
63524
  const agentBuilderNamespace = env2.AGENT_BUILDER;
63485
63525
  if (!agentBuilderNamespace || typeof agentBuilderNamespace.idFromName !== "function" || typeof agentBuilderNamespace.get !== "function") {
63486
63526
  throw new Error("Server misconfigured: AGENT_BUILDER Durable Object binding is required for platform auth");
63487
63527
  }
63488
63528
  const agentBuilderId = agentBuilderNamespace.idFromName("singleton");
63489
63529
  const agentBuilder = agentBuilderNamespace.get(agentBuilderId);
63490
- const username = identity.user.username;
63491
- let user = await agentBuilder.getUserByUsername(username);
63492
- if (!user) {
63493
- const legacyUsername = sanitizeUsername(`standard-agents-${identity.account.slug}`);
63494
- const legacyUser = legacyUsername !== username ? await agentBuilder.getUserByUsername(legacyUsername) : null;
63495
- if (legacyUser) {
63496
- user = await agentBuilder.updateUser(legacyUser.id, { username }) ?? legacyUser;
63497
- } else {
63498
- user = await agentBuilder.createUser({
63499
- username,
63500
- password_hash: await hashPassword(crypto.randomUUID()),
63501
- role: "admin"
63502
- });
63503
- }
63504
- }
63530
+ const user = await agentBuilder.upsertPlatformReplicaUser({
63531
+ platform_user_id: identity.user.id,
63532
+ username: identity.user.username,
63533
+ display_name: identity.user.display_name ?? null,
63534
+ email: identity.user.email ?? null,
63535
+ avatar_url: identity.user.avatar_url ?? null,
63536
+ role: identity.user.role
63537
+ });
63505
63538
  const token = generateUserToken();
63506
63539
  const tokenHash = await hashToken(token);
63507
63540
  const expiresAt = Math.floor(Date.now() / 1e3) + SESSION_TTL_SECONDS;
@@ -63521,6 +63554,94 @@ async function createPlatformLocalSession(env2) {
63521
63554
  platform: identity
63522
63555
  };
63523
63556
  }
63557
+
63558
+ // src/api/api-keys/index.get.ts
63559
+ var index_get_default = defineController2(async ({ req, env: env2 }) => {
63560
+ try {
63561
+ if (isPlatformHosted(env2)) {
63562
+ return Response.json({ error: "API keys are managed in the Standard Agents platform." }, { status: 410 });
63563
+ }
63564
+ const authResult = await requireAuth(req, env2);
63565
+ if (authResult instanceof Response) {
63566
+ return authResult;
63567
+ }
63568
+ if (authResult.authType === "super_admin") {
63569
+ return Response.json({ keys: [], message: "Super admin has no API keys. Create a user account to manage API keys." });
63570
+ }
63571
+ const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
63572
+ const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
63573
+ const keys = await agentBuilder.listApiKeys(authResult.user.id);
63574
+ return Response.json({ keys });
63575
+ } catch (error) {
63576
+ console.error("List API keys error:", error);
63577
+ return Response.json(
63578
+ { error: error.message || "Failed to list API keys" },
63579
+ { status: 500 }
63580
+ );
63581
+ }
63582
+ });
63583
+
63584
+ // src/api/api-keys/index.post.ts
63585
+ var index_post_default2 = defineController2(async ({ req, env: env2 }) => {
63586
+ try {
63587
+ if (isPlatformHosted(env2)) {
63588
+ return Response.json({ error: "API keys are managed in the Standard Agents platform." }, { status: 410 });
63589
+ }
63590
+ const authResult = await requireAuth(req, env2);
63591
+ if (authResult instanceof Response) {
63592
+ return authResult;
63593
+ }
63594
+ if (authResult.authType === "super_admin") {
63595
+ return Response.json(
63596
+ { error: "Super admin cannot create API keys. Please create a user account first." },
63597
+ { status: 400 }
63598
+ );
63599
+ }
63600
+ const body = await req.json();
63601
+ const { name: name15 } = body;
63602
+ if (!name15 || typeof name15 !== "string") {
63603
+ return Response.json(
63604
+ { error: "Name is required" },
63605
+ { status: 400 }
63606
+ );
63607
+ }
63608
+ if (name15.length < 1 || name15.length > 100) {
63609
+ return Response.json(
63610
+ { error: "Name must be between 1 and 100 characters" },
63611
+ { status: 400 }
63612
+ );
63613
+ }
63614
+ const apiKey = generateApiKey();
63615
+ const keyHash = await hashToken(apiKey);
63616
+ const keyPrefix = getTokenPrefix(apiKey);
63617
+ const lastFive = getLastChars(apiKey, 5);
63618
+ const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
63619
+ const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
63620
+ const id = await agentBuilder.createApiKey({
63621
+ name: name15,
63622
+ key_hash: keyHash,
63623
+ key_prefix: keyPrefix,
63624
+ last_five: lastFive,
63625
+ user_id: authResult.user.id
63626
+ });
63627
+ const now = Math.floor(Date.now() / 1e3);
63628
+ return Response.json({
63629
+ key: apiKey,
63630
+ // Only returned once on creation
63631
+ id,
63632
+ name: name15,
63633
+ key_prefix: keyPrefix,
63634
+ last_five: lastFive,
63635
+ created_at: now
63636
+ }, { status: 201 });
63637
+ } catch (error) {
63638
+ console.error("Create API key error:", error);
63639
+ return Response.json(
63640
+ { error: error.message || "Failed to create API key" },
63641
+ { status: 500 }
63642
+ );
63643
+ }
63644
+ });
63524
63645
  var STATE_RELATIVE_PATH = path5__default.join(".agents", "bootstrap-session.json");
63525
63646
  var PROJECT_ROOT_ENV_KEYS = ["INIT_CWD", "PWD", "npm_config_local_prefix"];
63526
63647
  function readEnvString(env2, key) {
@@ -64613,6 +64734,9 @@ var tools_get_default = defineController2(async ({ url, tools, prompts, promptNa
64613
64734
  // src/api/users/index.get.ts
64614
64735
  var index_get_default2 = defineController2(async ({ req, env: env2 }) => {
64615
64736
  try {
64737
+ if (isPlatformHosted(env2)) {
64738
+ return Response.json({ error: "Users are managed in the Standard Agents platform." }, { status: 410 });
64739
+ }
64616
64740
  const authResult = await requireAdmin(req, env2);
64617
64741
  if (authResult instanceof Response) {
64618
64742
  return authResult;
@@ -64644,6 +64768,9 @@ var index_get_default2 = defineController2(async ({ req, env: env2 }) => {
64644
64768
  var VALID_ROLES = ["admin", "user"];
64645
64769
  var index_post_default4 = defineController2(async ({ req, env: env2 }) => {
64646
64770
  try {
64771
+ if (isPlatformHosted(env2)) {
64772
+ return Response.json({ error: "Users are managed in the Standard Agents platform." }, { status: 410 });
64773
+ }
64647
64774
  const authResult = await requireAdmin(req, env2);
64648
64775
  if (authResult instanceof Response) {
64649
64776
  return authResult;
@@ -64827,6 +64954,9 @@ var name_get_default = defineController2(async ({ params, agents, prompts, promp
64827
64954
  // src/api/api-keys/[id].delete.ts
64828
64955
  var id_delete_default = defineController2(async ({ req, env: env2, params }) => {
64829
64956
  try {
64957
+ if (isPlatformHosted(env2)) {
64958
+ return Response.json({ error: "API keys are managed in the Standard Agents platform." }, { status: 410 });
64959
+ }
64830
64960
  const authResult = await requireAuth(req, env2);
64831
64961
  if (authResult instanceof Response) {
64832
64962
  return authResult;
@@ -65544,6 +65674,9 @@ var index_post_default6 = defineController2(async ({ req }) => {
65544
65674
  // src/api/users/[id].delete.ts
65545
65675
  var id_delete_default3 = defineController2(async ({ req, env: env2, params }) => {
65546
65676
  try {
65677
+ if (isPlatformHosted(env2)) {
65678
+ return Response.json({ error: "Users are managed in the Standard Agents platform." }, { status: 410 });
65679
+ }
65547
65680
  const authResult = await requireAdmin(req, env2);
65548
65681
  if (authResult instanceof Response) {
65549
65682
  return authResult;
@@ -65572,6 +65705,9 @@ var id_delete_default3 = defineController2(async ({ req, env: env2, params }) =>
65572
65705
  // src/api/users/[id].put.ts
65573
65706
  var id_put_default = defineController2(async ({ req, env: env2, params }) => {
65574
65707
  try {
65708
+ if (isPlatformHosted(env2)) {
65709
+ return Response.json({ error: "Users are managed in the Standard Agents platform." }, { status: 410 });
65710
+ }
65575
65711
  const authResult = await requireAdmin(req, env2);
65576
65712
  if (authResult instanceof Response) {
65577
65713
  return authResult;
@@ -65605,7 +65741,7 @@ var id_put_default = defineController2(async ({ req, env: env2, params }) => {
65605
65741
  updateParams.password_hash = await hashPassword(password);
65606
65742
  }
65607
65743
  if (role) {
65608
- updateParams.role = role;
65744
+ updateParams.role = role === "user" ? "user" : "admin";
65609
65745
  }
65610
65746
  const updatedUser = await agentBuilder.updateUser(id, updateParams);
65611
65747
  return Response.json({
@@ -65627,104 +65763,18 @@ var id_put_default = defineController2(async ({ req, env: env2, params }) => {
65627
65763
  });
65628
65764
 
65629
65765
  // src/api/auth/bootstrap.post.ts
65630
- function deriveManagedUsername(platformUserId) {
65631
- return `sa-${platformUserId}`;
65632
- }
65633
- function uniqueEndpoints(preferred, candidates) {
65634
- return Array.from(new Set([preferred, ...candidates].filter(Boolean)));
65635
- }
65636
- var bootstrap_post_default = defineController2(async ({ req, env: env2 }) => {
65766
+ var bootstrap_post_default = defineController2(async ({ env: env2 }) => {
65637
65767
  try {
65638
65768
  const platformTokenSession = await createPlatformLocalSession(env2);
65639
- if (platformTokenSession) {
65640
- return Response.json(platformTokenSession);
65769
+ if (!platformTokenSession) {
65770
+ return new Response(null, { status: 204 });
65641
65771
  }
65772
+ return Response.json(platformTokenSession);
65642
65773
  } catch (error) {
65643
- console.error("Platform auth bootstrap error:", error);
65644
- return Response.json(
65645
- { error: error instanceof Error ? error.message : "Failed to bootstrap platform auth" },
65646
- { status: 500 }
65647
- );
65774
+ const message = error instanceof Error ? error.message : "Failed to bootstrap platform auth";
65775
+ const status = message.includes("STANDARD_AGENTS_API_KEY") ? 401 : 502;
65776
+ return Response.json({ error: message }, { status });
65648
65777
  }
65649
- const bootstrap = findLocalBootstrapSession(void 0, env2);
65650
- const bootstrapState = bootstrap?.session;
65651
- if (!bootstrapState?.session_cookie) {
65652
- return new Response(null, { status: 204 });
65653
- }
65654
- const endpoints = uniqueEndpoints(
65655
- bootstrapState.endpoint,
65656
- resolvePlatformEndpointCandidates(req, env2)
65657
- );
65658
- let platformUser = null;
65659
- for (const endpoint of endpoints) {
65660
- try {
65661
- const response = await fetch(`${endpoint}/auth/session`, {
65662
- method: "GET",
65663
- headers: {
65664
- Cookie: bootstrapState.session_cookie
65665
- }
65666
- });
65667
- if (response.status === 401) {
65668
- return Response.json(
65669
- { error: "Stored Standard Agents session is no longer valid. Run `agents login` again." },
65670
- { status: 401 }
65671
- );
65672
- }
65673
- if (!response.ok) {
65674
- continue;
65675
- }
65676
- const payload = await response.json().catch(() => ({}));
65677
- platformUser = payload.user ?? null;
65678
- break;
65679
- } catch {
65680
- continue;
65681
- }
65682
- }
65683
- const fallbackPlatformUserId = bootstrapState.user?.id;
65684
- const platformUserId = platformUser?.id ?? fallbackPlatformUserId;
65685
- if (!platformUserId) {
65686
- return Response.json(
65687
- { error: "Bad Gateway: platform API unreachable" },
65688
- { status: 502 }
65689
- );
65690
- }
65691
- const username = deriveManagedUsername(platformUserId);
65692
- if (!env2.AGENT_BUILDER || typeof env2.AGENT_BUILDER.idFromName !== "function") {
65693
- return Response.json(
65694
- { error: "Server misconfigured: AGENT_BUILDER Durable Object binding is required for platform auth" },
65695
- { status: 500 }
65696
- );
65697
- }
65698
- const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
65699
- const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
65700
- let user = await agentBuilder.getUserByUsername(username);
65701
- if (!user) {
65702
- user = await agentBuilder.createUser({
65703
- username,
65704
- password_hash: await hashPassword(crypto.randomUUID()),
65705
- role: "admin"
65706
- });
65707
- }
65708
- const token = generateUserToken();
65709
- const tokenHash = await hashToken(token);
65710
- const expiresAt = Math.floor(Date.now() / 1e3) + 30 * 24 * 60 * 60;
65711
- await agentBuilder.createSession({
65712
- user_id: user.id,
65713
- token_hash: tokenHash,
65714
- expires_at: expiresAt
65715
- });
65716
- return Response.json({
65717
- token,
65718
- user: {
65719
- id: user.id,
65720
- username: user.username,
65721
- role: user.role
65722
- },
65723
- platform_user: {
65724
- id: platformUserId,
65725
- email: platformUser?.email ?? bootstrapState.user?.email
65726
- }
65727
- });
65728
65778
  });
65729
65779
 
65730
65780
  // src/api/auth/config.get.ts
@@ -65734,11 +65784,16 @@ var config_get_default2 = defineController2(async ({ req, env: env2 }) => {
65734
65784
  const configuredPlatformEndpoint = resolvePlatformEndpoint(req, env2);
65735
65785
  const platformConnected = hasPlatformApiKey(env2) || !!findLocalBootstrapSession(void 0, env2);
65736
65786
  const localPassword = typeof env2.SUPER_ADMIN_PASSWORD === "string" && env2.SUPER_ADMIN_PASSWORD.length > 0;
65787
+ const hosted = isPlatformHosted(env2);
65788
+ const standardAgentsLogin = hosted;
65737
65789
  return {
65738
65790
  github: githubConfigured,
65739
65791
  google: googleConfigured,
65740
65792
  platformConnected,
65741
65793
  localPassword,
65794
+ hosted,
65795
+ standardAgentsLogin,
65796
+ platformLoginUrl: hosted ? platformLoginUrl(req, env2, "/") : void 0,
65742
65797
  platformEndpoint: hasPlatformApiKey(env2) ? platformEndpoint(env2) : configuredPlatformEndpoint
65743
65798
  };
65744
65799
  });
@@ -65746,6 +65801,12 @@ var config_get_default2 = defineController2(async ({ req, env: env2 }) => {
65746
65801
  // src/api/auth/login.post.ts
65747
65802
  var login_post_default = defineController2(async ({ req, env: env2 }) => {
65748
65803
  try {
65804
+ if (isPlatformHosted(env2)) {
65805
+ return Response.json(
65806
+ { error: "Hosted instances authenticate through the Standard Agents platform." },
65807
+ { status: 404 }
65808
+ );
65809
+ }
65749
65810
  const body = await req.json();
65750
65811
  const { username, password } = body;
65751
65812
  if (!password) {
@@ -65826,28 +65887,28 @@ var login_post_default = defineController2(async ({ req, env: env2 }) => {
65826
65887
 
65827
65888
  // src/api/auth/logout.post.ts
65828
65889
  var logout_post_default = defineController2(async ({ req, env: env2 }) => {
65890
+ const clearCookie = (body, status = 200) => new Response(JSON.stringify(body), {
65891
+ status,
65892
+ headers: {
65893
+ "Content-Type": "application/json",
65894
+ "Set-Cookie": buildSessionCookie(req, "", 0)
65895
+ }
65896
+ });
65829
65897
  try {
65830
65898
  const authHeader = req.headers.get("Authorization");
65831
- if (!authHeader || !authHeader.startsWith("Bearer ")) {
65832
- return Response.json({ error: "Unauthorized" }, { status: 401 });
65899
+ const token = authHeader && authHeader.startsWith("Bearer ") ? authHeader.substring(7) : readSessionCookie(req);
65900
+ if (!token) {
65901
+ return clearCookie({ success: true });
65833
65902
  }
65834
- const token = authHeader.substring(7);
65835
- if (token.includes(".")) {
65836
- return Response.json({ success: true });
65837
- }
65838
- if (isValidUserToken(token)) {
65903
+ if (!token.includes(".") && isValidUserToken(token)) {
65839
65904
  const tokenHash = await hashToken(token);
65840
- const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
65841
- const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
65905
+ const agentBuilder = env2.AGENT_BUILDER.get(env2.AGENT_BUILDER.idFromName("singleton"));
65842
65906
  await agentBuilder.deleteSession(tokenHash);
65843
65907
  }
65844
- return Response.json({ success: true });
65908
+ return clearCookie({ success: true });
65845
65909
  } catch (error) {
65846
65910
  console.error("Logout error:", error);
65847
- return Response.json(
65848
- { error: error.message || "Logout failed" },
65849
- { status: 500 }
65850
- );
65911
+ return clearCookie({ error: error.message || "Logout failed" }, 500);
65851
65912
  }
65852
65913
  });
65853
65914
 
@@ -65871,6 +65932,100 @@ var me_get_default = defineController2(async ({ req, env: env2 }) => {
65871
65932
  }
65872
65933
  });
65873
65934
 
65935
+ // src/utils/platform-signed-payload.ts
65936
+ var encoder = new TextEncoder();
65937
+ var decoder = new TextDecoder();
65938
+ function base64UrlToBytes(value) {
65939
+ const padded = value.replace(/-/g, "+").replace(/_/g, "/") + "=".repeat((4 - value.length % 4) % 4);
65940
+ const binary = atob(padded);
65941
+ const bytes = new Uint8Array(binary.length);
65942
+ for (let index = 0; index < binary.length; index += 1) {
65943
+ bytes[index] = binary.charCodeAt(index);
65944
+ }
65945
+ return bytes;
65946
+ }
65947
+ function decodeJson(value) {
65948
+ return JSON.parse(decoder.decode(base64UrlToBytes(value)));
65949
+ }
65950
+ function parsePublicJwk(value) {
65951
+ if (typeof value !== "string" || !value.trim()) return null;
65952
+ try {
65953
+ const parsed = JSON.parse(value);
65954
+ if (parsed.kty !== "EC" || parsed.crv !== "P-256" || !parsed.x || !parsed.y) {
65955
+ return null;
65956
+ }
65957
+ return parsed;
65958
+ } catch {
65959
+ return null;
65960
+ }
65961
+ }
65962
+ async function importPublicKey(jwk) {
65963
+ return crypto.subtle.importKey(
65964
+ "jwk",
65965
+ jwk,
65966
+ { name: "ECDSA", namedCurve: "P-256" },
65967
+ false,
65968
+ ["verify"]
65969
+ );
65970
+ }
65971
+ async function verifyPlatformSignedPayload(token, publicJwkValue, options) {
65972
+ const publicJwk = parsePublicJwk(publicJwkValue);
65973
+ if (!publicJwk) return null;
65974
+ const normalized = token.startsWith("sap_") ? token.slice(4) : token;
65975
+ const parts = normalized.split(".");
65976
+ if (parts.length !== 3) return null;
65977
+ const [headerB64, payloadB64, signatureB64] = parts;
65978
+ let header;
65979
+ let payload;
65980
+ try {
65981
+ header = decodeJson(headerB64);
65982
+ payload = decodeJson(payloadB64);
65983
+ } catch {
65984
+ return null;
65985
+ }
65986
+ if (header.alg !== "ES256" || payload.kind !== options.kind) return null;
65987
+ if (options.projectId && payload.project_id !== options.projectId) return null;
65988
+ if (typeof payload.exp !== "number" || payload.exp < Math.floor(Date.now() / 1e3)) {
65989
+ return null;
65990
+ }
65991
+ const key = await importPublicKey(publicJwk);
65992
+ const signed = encoder.encode(`${headerB64}.${payloadB64}`);
65993
+ const signature = base64UrlToBytes(signatureB64);
65994
+ const verified = await crypto.subtle.verify(
65995
+ { name: "ECDSA", hash: "SHA-256" },
65996
+ key,
65997
+ signature,
65998
+ signed
65999
+ );
66000
+ return verified ? payload : null;
66001
+ }
66002
+
66003
+ // src/api/auth/platform-replica.post.ts
66004
+ var platform_replica_post_default = defineController2(async ({ req, env: env2 }) => {
66005
+ const body = await req.json().catch(() => null);
66006
+ const token = typeof body?.snapshot === "string" ? body.snapshot : req.headers.get("Authorization")?.startsWith("Bearer ") ? req.headers.get("Authorization").slice("Bearer ".length) : null;
66007
+ if (!token) {
66008
+ return Response.json({ error: "Missing replica snapshot" }, { status: 400 });
66009
+ }
66010
+ const payload = await verifyPlatformSignedPayload(
66011
+ token,
66012
+ env2.STANDARD_AGENTS_AUTH_PUBLIC_KEY_JWK ?? env2.STANDARD_AGENTS_AUTH_PUBLIC_KEY,
66013
+ {
66014
+ kind: "instance_snapshot",
66015
+ projectId: typeof env2.STANDARD_AGENTS_PROJECT_ID === "string" ? env2.STANDARD_AGENTS_PROJECT_ID : void 0
66016
+ }
66017
+ );
66018
+ if (!payload || !Array.isArray(payload.users)) {
66019
+ return Response.json({ error: "Invalid replica snapshot" }, { status: 401 });
66020
+ }
66021
+ const agentBuilder = env2.AGENT_BUILDER.get(env2.AGENT_BUILDER.idFromName("singleton"));
66022
+ const result = await agentBuilder.applyPlatformReplicaSnapshot({
66023
+ users: payload.users,
66024
+ api_keys: payload.api_keys ?? []
66025
+ });
66026
+ return Response.json({ ok: true, ...result });
66027
+ });
66028
+
65874
66029
  // src/api/envs/_shared.ts
65875
66030
  function buildScopedEnvResponse(entries) {
65876
66031
  const variables = [...entries].sort((a, b) => a.name.localeCompare(b.name)).map((entry) => ({
@@ -66254,6 +66409,12 @@ var npm_token_status_get_default = defineController2(async ({ env: env2 }) => {
66254
66409
 
66255
66410
  // src/api/platform/[...path].ts
66256
66411
  var path_default = defineController2(async ({ req, params, env: env2, url }) => {
66412
+ if (isPlatformHosted(env2)) {
66413
+ return Response.json(
66414
+ { error: "Platform proxy is disabled on hosted instances" },
66415
+ { status: 410 }
66416
+ );
66417
+ }
66257
66418
  const endpoints = resolvePlatformEndpointCandidates(req, env2);
66258
66419
  const apiKey = env2.PLATFORM_API_KEY;
66259
66420
  if (endpoints.length === 0 || !apiKey) {
@@ -66293,7 +66454,7 @@ var path_default = defineController2(async ({ req, params, env: env2, url }) =>
66293
66454
  });
66294
66455
 
66295
66456
  // src/api/platform-auth/bootstrap.post.ts
66296
- function uniqueEndpoints2(preferred, candidates) {
66457
+ function uniqueEndpoints(preferred, candidates) {
66297
66458
  return Array.from(new Set([preferred, ...candidates].filter((value) => Boolean(value))));
66298
66459
  }
66299
66460
  function buildSessionCookieHeader(req, sessionCookie) {
@@ -66307,6 +66468,12 @@ function buildSessionCookieHeader(req, sessionCookie) {
66307
66468
  return `${sessionCookie}; ${attributes.join("; ")}`;
66308
66469
  }
66309
66470
  var bootstrap_post_default2 = defineController2(async ({ req, env: env2 }) => {
66471
+ if (isPlatformHosted(env2)) {
66472
+ return Response.json(
66473
+ { error: "Platform auth bridge is disabled on hosted instances" },
66474
+ { status: 410 }
66475
+ );
66476
+ }
66310
66477
  const requestCookie = req.headers.get("Cookie")?.trim() || "";
66311
66478
  const configuredEndpoints = resolvePlatformEndpointCandidates(req, env2);
66312
66479
  let cookie = requestCookie;
@@ -66316,7 +66483,7 @@ var bootstrap_post_default2 = defineController2(async ({ req, env: env2 }) => {
66316
66483
  const bootstrap = findLocalBootstrapSession(void 0, env2)?.session;
66317
66484
  if (bootstrap?.session_cookie) {
66318
66485
  cookie = bootstrap.session_cookie;
66319
- endpoints = uniqueEndpoints2(bootstrap.endpoint, configuredEndpoints);
66486
+ endpoints = uniqueEndpoints(bootstrap.endpoint, configuredEndpoints);
66320
66487
  bootstrappedFromProject = true;
66321
66488
  } else {
66322
66489
  const localSession = await createPlatformLocalSession(env2);
@@ -66377,6 +66544,12 @@ var bootstrap_post_default2 = defineController2(async ({ req, env: env2 }) => {
66377
66544
 
66378
66545
  // src/api/platform-auth/login.post.ts
66379
66546
  var login_post_default2 = defineController2(async ({ req, env: env2 }) => {
66547
+ if (isPlatformHosted(env2)) {
66548
+ return Response.json(
66549
+ { error: "Platform auth bridge is disabled on hosted instances" },
66550
+ { status: 410 }
66551
+ );
66552
+ }
66380
66553
  const endpoints = resolvePlatformEndpointCandidates(req, env2);
66381
66554
  if (endpoints.length === 0) {
66382
66555
  const localSession = await createPlatformLocalSession(env2);
@@ -66429,6 +66602,9 @@ var login_post_default2 = defineController2(async ({ req, env: env2 }) => {
66429
66602
 
66430
66603
  // src/api/platform-auth/logout.post.ts
66431
66604
  var logout_post_default2 = defineController2(async ({ req, env: env2 }) => {
66605
+ if (isPlatformHosted(env2)) {
66606
+ return Response.json({ success: true });
66607
+ }
66432
66608
  const endpoints = resolvePlatformEndpointCandidates(req, env2);
66433
66609
  if (endpoints.length === 0) {
66434
66610
  return Response.json({ success: true });
@@ -66466,7 +66642,7 @@ var logout_post_default2 = defineController2(async ({ req, env: env2 }) => {
66466
66642
  });
66467
66643
 
66468
66644
  // src/api/platform-auth/me.get.ts
66469
- function uniqueEndpoints3(preferred, candidates) {
66645
+ function uniqueEndpoints2(preferred, candidates) {
66470
66646
  return Array.from(new Set([preferred, ...candidates].filter((value) => Boolean(value))));
66471
66647
  }
66472
66648
  function buildSessionCookieHeader2(req, sessionCookie) {
@@ -66480,6 +66656,12 @@ function buildSessionCookieHeader2(req, sessionCookie) {
66480
66656
  return `${sessionCookie}; ${attributes.join("; ")}`;
66481
66657
  }
66482
66658
  var me_get_default2 = defineController2(async ({ req, env: env2 }) => {
66659
+ if (isPlatformHosted(env2)) {
66660
+ return Response.json(
66661
+ { error: "Platform auth bridge is disabled on hosted instances" },
66662
+ { status: 410 }
66663
+ );
66664
+ }
66483
66665
  const requestCookie = req.headers.get("Cookie")?.trim() || "";
66484
66666
  const configuredEndpoints = resolvePlatformEndpointCandidates(req, env2);
66485
66667
  let cookie = requestCookie;
@@ -66489,7 +66671,7 @@ var me_get_default2 = defineController2(async ({ req, env: env2 }) => {
66489
66671
  const bootstrap = findLocalBootstrapSession(void 0, env2)?.session;
66490
66672
  if (bootstrap?.session_cookie) {
66491
66673
  cookie = bootstrap.session_cookie;
66492
- endpoints = uniqueEndpoints3(bootstrap.endpoint, configuredEndpoints);
66674
+ endpoints = uniqueEndpoints2(bootstrap.endpoint, configuredEndpoints);
66493
66675
  bootstrappedFromProject = true;
66494
66676
  } else {
66495
66677
  const identity = await getPlatformIdentity(env2);
@@ -66605,6 +66787,12 @@ async function proxyPlatformSessionRequest({
66605
66787
 
66606
66788
  // src/api/platform-session/[...path].ts
66607
66789
  var path_default2 = defineController2(async ({ req, params, env: env2, url }) => {
66790
+ if (isPlatformHosted(env2)) {
66791
+ return Response.json(
66792
+ { error: "Platform session proxy is disabled on hosted instances" },
66793
+ { status: 410 }
66794
+ );
66795
+ }
66608
66796
  if (!req.headers.get("Cookie") && hasPlatformApiKey(env2)) {
66609
66797
  return proxyPlatformSessionRequest({ req, params, env: env2 });
66610
66798
  }
@@ -68755,6 +68943,76 @@ var name_get_default7 = defineController2(async ({ params, url, prompts, agents,
68755
68943
  return Response.json({ variables });
68756
68944
  });
68757
68945
 
68946
+ // src/api/auth/sa/callback.get.ts
68947
+ var SESSION_TTL_SECONDS2 = 30 * 24 * 60 * 60;
68948
+ function safeReturnTo(value) {
68949
+ if (!value || !value.startsWith("/") || value.startsWith("//")) return "/";
68950
+ return value;
68951
+ }
68952
+ function failRedirect(req, reason) {
68953
+ const origin = new URL(req.url).origin;
68954
+ return new Response(null, {
68955
+ status: 302,
68956
+ headers: { Location: `${origin}/login?sa_error=${encodeURIComponent(reason)}` }
68957
+ });
68958
+ }
68959
+ var callback_get_default = defineController2(async ({ req, env: env2 }) => {
68960
+ if (!isPlatformHosted(env2)) {
68961
+ return failRedirect(req, "not_hosted");
68962
+ }
68963
+ const url = new URL(req.url);
68964
+ const handoff = url.searchParams.get("handoff") || url.searchParams.get("token");
68965
+ if (!handoff) {
68966
+ return failRedirect(req, "invalid_response");
68967
+ }
68968
+ const configuredProjectId = typeof env2.STANDARD_AGENTS_PROJECT_ID === "string" ? env2.STANDARD_AGENTS_PROJECT_ID : void 0;
68969
+ const payload = await verifyPlatformSignedPayload(
68970
+ handoff,
68971
+ env2.STANDARD_AGENTS_AUTH_PUBLIC_KEY_JWK ?? env2.STANDARD_AGENTS_AUTH_PUBLIC_KEY,
68972
+ {
68973
+ kind: "instance_handoff",
68974
+ projectId: configuredProjectId
68975
+ }
68976
+ );
68977
+ if (!payload || !payload.platform_user_id || !payload.role) {
68978
+ return failRedirect(req, "forbidden");
68979
+ }
68980
+ if (!configuredProjectId && payload.project_id !== hostedInstanceRedirectId(req, env2)) {
68981
+ return failRedirect(req, "forbidden");
68982
+ }
68983
+ const session = await mintLocalSessionForPlatformUser(env2, {
68984
+ platform_user_id: payload.platform_user_id,
68985
+ username: payload.username ?? null,
68986
+ display_name: payload.display_name ?? null,
68987
+ email: payload.email ?? null,
68988
+ avatar_url: payload.avatar_url ?? null,
68989
+ role: payload.role
68990
+ });
68991
+ const returnTo = safeReturnTo(url.searchParams.get("return_to"));
68992
+ return new Response(null, {
68993
+ status: 302,
68994
+ headers: {
68995
+ Location: `${url.origin}${returnTo}`,
68996
+ "Set-Cookie": buildSessionCookie(req, session.token, SESSION_TTL_SECONDS2)
68997
+ }
68998
+ });
68999
+ });
69000
+
69001
+ // src/api/auth/sa/start.get.ts
69002
+ var start_get_default = defineController2(async ({ req, env: env2 }) => {
69003
+ if (!isPlatformHosted(env2)) {
69004
+ return Response.json({ error: "Standard Agents hosted login is only available on deployed instances." }, { status: 404 });
69005
+ }
69006
+ const url = new URL(req.url);
69007
+ const returnTo = url.searchParams.get("return_to") || "/";
69008
+ return new Response(null, {
69009
+ status: 302,
69010
+ headers: {
69011
+ Location: platformLoginUrl(req, env2, returnTo)
69012
+ }
69013
+ });
69014
+ });
69015
+
68758
69016
  // src/api/users/me/env.get.ts
68759
69017
  var env_get_default2 = defineController2(async ({ req, env: env2 }) => {
68760
69018
  try {
@@ -69852,6 +70110,7 @@ var routeHandlers = {
69852
70110
  "POST:/auth/login": login_post_default,
69853
70111
  "POST:/auth/logout": logout_post_default,
69854
70112
  "GET:/auth/me": me_get_default,
70113
+ "POST:/auth/platform-replica": platform_replica_post_default,
69855
70114
  "GET:/envs/instance": instance_get_default,
69856
70115
  "PATCH:/envs/instance": instance_patch_default,
69857
70116
  "POST:/models/available": available_post_default,
@@ -69900,6 +70159,8 @@ var routeHandlers = {
69900
70159
  "GET:/variables/agents/:name": name_get_default5,
69901
70160
  "GET:/variables/prompts/:name": name_get_default6,
69902
70161
  "GET:/variables/tools/:name": name_get_default7,
70162
+ "GET:/auth/sa/callback": callback_get_default,
70163
+ "GET:/auth/sa/start": start_get_default,
69903
70164
  "GET:/users/me/env": env_get_default2,
69904
70165
  "PATCH:/users/me/env": env_patch_default2,
69905
70166
  "DELETE:/threads/:id/fs/**": path_default3,