@clawos-dev/clawd 0.2.86 → 0.2.87-beta.164.a38a7cd

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 (2) hide show
  1. package/dist/cli.cjs +25 -13
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -27414,6 +27414,12 @@ var UPLOAD_MIME_ALLOW = /* @__PURE__ */ new Set([
27414
27414
  ]);
27415
27415
  var UPLOAD_MIME_ALLOW_PREFIX = ["text/"];
27416
27416
  var UPLOAD_MAX_BYTES = 25 * 1024 * 1024;
27417
+ var UPLOAD_CORS_HEADERS = {
27418
+ "Access-Control-Allow-Origin": "*",
27419
+ "Access-Control-Allow-Methods": "POST, OPTIONS",
27420
+ "Access-Control-Allow-Headers": "Authorization, Content-Type",
27421
+ "Access-Control-Max-Age": "86400"
27422
+ };
27417
27423
  function isUploadMimeAllowed(mime) {
27418
27424
  if (UPLOAD_MIME_ALLOW.has(mime)) return true;
27419
27425
  return UPLOAD_MIME_ALLOW_PREFIX.some((p2) => mime.startsWith(p2));
@@ -27441,6 +27447,11 @@ function createHttpRouter(deps) {
27441
27447
  if (!url.pathname.startsWith("/session/") && !url.pathname.startsWith("/files/") && url.pathname !== "/attachments/upload") {
27442
27448
  return false;
27443
27449
  }
27450
+ if (url.pathname === "/attachments/upload" && req.method === "OPTIONS") {
27451
+ res.writeHead(204, UPLOAD_CORS_HEADERS);
27452
+ res.end();
27453
+ return true;
27454
+ }
27444
27455
  if (url.pathname.startsWith("/files/") && req.method === "GET") {
27445
27456
  const secret = deps.getSignSecret?.();
27446
27457
  if (!secret) {
@@ -27479,13 +27490,14 @@ function createHttpRouter(deps) {
27479
27490
  return true;
27480
27491
  }
27481
27492
  if (url.pathname === "/attachments/upload" && req.method === "POST") {
27493
+ const sendUploadJson = (status, body) => sendJson(res, status, body, UPLOAD_CORS_HEADERS);
27482
27494
  if (ctx.role !== "owner") {
27483
- sendJson(res, 403, { code: "FORBIDDEN", message: "owner only" });
27495
+ sendUploadJson(403, { code: "FORBIDDEN", message: "owner only" });
27484
27496
  return true;
27485
27497
  }
27486
27498
  const up = deps.attachmentUpload;
27487
27499
  if (!up) {
27488
- sendJson(res, 501, { code: "NOT_IMPLEMENTED", message: "attachment upload not wired" });
27500
+ sendUploadJson(501, { code: "NOT_IMPLEMENTED", message: "attachment upload not wired" });
27489
27501
  return true;
27490
27502
  }
27491
27503
  const sessionId = url.searchParams.get("sessionId");
@@ -27493,14 +27505,14 @@ function createHttpRouter(deps) {
27493
27505
  const mimeType = url.searchParams.get("mimeType");
27494
27506
  const contentLengthRaw = req.headers["content-length"];
27495
27507
  if (!sessionId || !fileName || !mimeType || !contentLengthRaw) {
27496
- sendJson(res, 400, {
27508
+ sendUploadJson(400, {
27497
27509
  code: "INVALID_PARAM",
27498
27510
  message: "missing sessionId/fileName/mimeType/Content-Length"
27499
27511
  });
27500
27512
  return true;
27501
27513
  }
27502
27514
  if (!isValidUploadFileName(fileName)) {
27503
- sendJson(res, 400, {
27515
+ sendUploadJson(400, {
27504
27516
  code: "INVALID_FILENAME",
27505
27517
  message: `fileName must be a plain basename (no path separators, no dotfiles): ${fileName}`
27506
27518
  });
@@ -27508,18 +27520,18 @@ function createHttpRouter(deps) {
27508
27520
  }
27509
27521
  const contentLength = Number.parseInt(contentLengthRaw, 10);
27510
27522
  if (!Number.isFinite(contentLength) || contentLength < 0) {
27511
- sendJson(res, 400, { code: "INVALID_PARAM", message: "malformed Content-Length" });
27523
+ sendUploadJson(400, { code: "INVALID_PARAM", message: "malformed Content-Length" });
27512
27524
  return true;
27513
27525
  }
27514
27526
  if (contentLength > UPLOAD_MAX_BYTES) {
27515
- sendJson(res, 413, {
27527
+ sendUploadJson(413, {
27516
27528
  code: "FILE_TOO_LARGE",
27517
27529
  message: `max ${UPLOAD_MAX_BYTES} bytes`
27518
27530
  });
27519
27531
  return true;
27520
27532
  }
27521
27533
  if (!isUploadMimeAllowed(mimeType)) {
27522
- sendJson(res, 400, {
27534
+ sendUploadJson(400, {
27523
27535
  code: "UNSUPPORTED_MIME",
27524
27536
  message: `mime ${mimeType} not allowed`
27525
27537
  });
@@ -27528,12 +27540,12 @@ function createHttpRouter(deps) {
27528
27540
  const sessionDir = up.getSessionDir(sessionId);
27529
27541
  const scope = up.getSessionScope(sessionId);
27530
27542
  if (!sessionDir || !scope) {
27531
- sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sessionId} not found` });
27543
+ sendUploadJson(404, { code: "NOT_FOUND", message: `session ${sessionId} not found` });
27532
27544
  return true;
27533
27545
  }
27534
27546
  const httpBaseUrl = up.getHttpBaseUrl();
27535
27547
  if (!httpBaseUrl) {
27536
- sendJson(res, 503, {
27548
+ sendUploadJson(503, {
27537
27549
  code: "TUNNEL_NOT_READY",
27538
27550
  message: "httpBaseUrl unavailable"
27539
27551
  });
@@ -27541,7 +27553,7 @@ function createHttpRouter(deps) {
27541
27553
  }
27542
27554
  const secret = deps.getSignSecret?.();
27543
27555
  if (!secret) {
27544
- sendJson(res, 501, {
27556
+ sendUploadJson(501, {
27545
27557
  code: "NOT_IMPLEMENTED",
27546
27558
  message: "sign secret unavailable (noAuth?)"
27547
27559
  });
@@ -27560,7 +27572,7 @@ function createHttpRouter(deps) {
27560
27572
  });
27561
27573
  const parts = signUrlParts(secret, result.absPath, null);
27562
27574
  const fullUrl = buildSignedFileUrl(httpBaseUrl, parts);
27563
- sendJson(res, 200, {
27575
+ sendUploadJson(200, {
27564
27576
  attachmentId: result.attachmentId,
27565
27577
  url: fullUrl,
27566
27578
  relPath: result.relPath,
@@ -27570,10 +27582,10 @@ function createHttpRouter(deps) {
27570
27582
  } catch (err) {
27571
27583
  if (err instanceof UploadError) {
27572
27584
  const status = err.code === "SIZE_MISMATCH" ? 400 : 500;
27573
- sendJson(res, status, { code: err.code, message: err.message });
27585
+ sendUploadJson(status, { code: err.code, message: err.message });
27574
27586
  } else {
27575
27587
  deps.logger?.warn("attachment upload failed", { err: err.message });
27576
- sendJson(res, 500, { code: "STORAGE_ERROR", message: err.message });
27588
+ sendUploadJson(500, { code: "STORAGE_ERROR", message: err.message });
27577
27589
  }
27578
27590
  }
27579
27591
  return true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawos-dev/clawd",
3
- "version": "0.2.86",
3
+ "version": "0.2.87-beta.164.a38a7cd",
4
4
  "description": "Standalone clawd daemon — Claude Code (and future Codex) session server over WebSocket",
5
5
  "type": "module",
6
6
  "license": "MIT",