@clawos-dev/clawd 0.2.648 → 0.2.650

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.
@@ -34364,6 +34364,40 @@ var CloudVolumeGetResultSchema = external_exports.object({
34364
34364
  volume: CloudVolumeUsageSchema.nullable()
34365
34365
  }).strict();
34366
34366
 
34367
+ // ../protocol/src/attachment-upload-policy.ts
34368
+ var MAX_ATTACHMENT_BYTES = 25 * 1024 * 1024;
34369
+ var EXTENSION_MIME = {
34370
+ ".png": "image/png",
34371
+ ".jpg": "image/jpeg",
34372
+ ".jpeg": "image/jpeg",
34373
+ ".gif": "image/gif",
34374
+ ".webp": "image/webp",
34375
+ ".pdf": "application/pdf",
34376
+ ".txt": "text/plain",
34377
+ ".md": "text/plain",
34378
+ ".markdown": "text/plain",
34379
+ ".csv": "text/plain",
34380
+ ".log": "text/plain",
34381
+ ".json": "application/json",
34382
+ ".xml": "application/xml",
34383
+ ".yaml": "application/yaml",
34384
+ ".yml": "application/yaml",
34385
+ ".html": "text/html",
34386
+ ".conf": "text/plain",
34387
+ ".cfg": "text/plain",
34388
+ ".ini": "text/plain",
34389
+ ".toml": "text/plain"
34390
+ };
34391
+ var ACCEPTED_MIME = /* @__PURE__ */ new Set([
34392
+ ...Object.values(EXTENSION_MIME),
34393
+ "application/x-yaml"
34394
+ ]);
34395
+ var CHAT_INPUT_FILE_ACCEPT = [
34396
+ ...ACCEPTED_MIME,
34397
+ "text/*",
34398
+ ...Object.keys(EXTENSION_MIME)
34399
+ ].join(",");
34400
+
34367
34401
  // ../protocol/src/log.ts
34368
34402
  var LOG_SOURCES = ["daemon", "main", "renderer"];
34369
34403
  var LogSourceSchema = external_exports.enum(LOG_SOURCES);
package/dist/cli.cjs CHANGED
@@ -9669,6 +9669,55 @@ var init_persona_mode = __esm({
9669
9669
  }
9670
9670
  });
9671
9671
 
9672
+ // ../protocol/src/attachment-upload-policy.ts
9673
+ function resolveAttachmentUploadMime(fileName, mimeType) {
9674
+ const mime = mimeType.split(";", 1)[0].trim().toLowerCase();
9675
+ if (mime === "" || mime === "application/octet-stream") {
9676
+ const extensionIndex = fileName.lastIndexOf(".");
9677
+ const extension2 = extensionIndex > 0 ? fileName.slice(extensionIndex).toLowerCase() : "";
9678
+ return EXTENSION_MIME[extension2] ?? null;
9679
+ }
9680
+ return ACCEPTED_MIME.has(mime) || mime.startsWith("text/") ? mime : null;
9681
+ }
9682
+ var MAX_ATTACHMENT_BYTES, EXTENSION_MIME, ACCEPTED_MIME, CHAT_INPUT_FILE_ACCEPT;
9683
+ var init_attachment_upload_policy = __esm({
9684
+ "../protocol/src/attachment-upload-policy.ts"() {
9685
+ "use strict";
9686
+ MAX_ATTACHMENT_BYTES = 25 * 1024 * 1024;
9687
+ EXTENSION_MIME = {
9688
+ ".png": "image/png",
9689
+ ".jpg": "image/jpeg",
9690
+ ".jpeg": "image/jpeg",
9691
+ ".gif": "image/gif",
9692
+ ".webp": "image/webp",
9693
+ ".pdf": "application/pdf",
9694
+ ".txt": "text/plain",
9695
+ ".md": "text/plain",
9696
+ ".markdown": "text/plain",
9697
+ ".csv": "text/plain",
9698
+ ".log": "text/plain",
9699
+ ".json": "application/json",
9700
+ ".xml": "application/xml",
9701
+ ".yaml": "application/yaml",
9702
+ ".yml": "application/yaml",
9703
+ ".html": "text/html",
9704
+ ".conf": "text/plain",
9705
+ ".cfg": "text/plain",
9706
+ ".ini": "text/plain",
9707
+ ".toml": "text/plain"
9708
+ };
9709
+ ACCEPTED_MIME = /* @__PURE__ */ new Set([
9710
+ ...Object.values(EXTENSION_MIME),
9711
+ "application/x-yaml"
9712
+ ]);
9713
+ CHAT_INPUT_FILE_ACCEPT = [
9714
+ ...ACCEPTED_MIME,
9715
+ "text/*",
9716
+ ...Object.keys(EXTENSION_MIME)
9717
+ ].join(",");
9718
+ }
9719
+ });
9720
+
9672
9721
  // ../protocol/src/log.ts
9673
9722
  var LOG_SOURCES, LogSourceSchema, LOG_LEVELS, LogLevelSchema, LogRecordSchema;
9674
9723
  var init_log = __esm({
@@ -9825,6 +9874,7 @@ var init_runtime = __esm({
9825
9874
  init_persona_schemas();
9826
9875
  init_persona_mode();
9827
9876
  init_attachment_schemas();
9877
+ init_attachment_upload_policy();
9828
9878
  init_principal();
9829
9879
  init_capability();
9830
9880
  init_inbox();
@@ -61489,6 +61539,7 @@ async function storeGithubAuth(args) {
61489
61539
  init_zod();
61490
61540
  var SLUG = "ottin4ttc/clawos";
61491
61541
  var WORKFLOW = ".github/workflows/base-image-acr.yml";
61542
+ var DOCKERFILE = "cloud-host/Dockerfile.base";
61492
61543
  var SHA = external_exports.string().regex(/^[a-f0-9]{40}$/);
61493
61544
  var SourceSchema = external_exports.object({ cloudHost: SHA, workflow: SHA });
61494
61545
  var BaseSchema = external_exports.object({
@@ -61514,6 +61565,25 @@ async function currentSource(api) {
61514
61565
  if (!source.success) throw new Error("\u5E95\u5EA7\u6E90\u7801\u7248\u672C\u8BB0\u5F55\u4E0D\u5B8C\u6574\uFF0C\u8BF7\u5237\u65B0\u540E\u518D\u53D1\u5E03");
61515
61566
  return { commit, source: source.data };
61516
61567
  }
61568
+ function dockerfileInputs(text) {
61569
+ if (!/^\s*FROM\s+/im.test(text)) throw new Error("\u8BFB\u4E0D\u5230\u53EF\u4FE1\u7684\u5E95\u5EA7\u6784\u5EFA\u914D\u65B9");
61570
+ const logical = text.replace(/\\\r?\n/g, " ");
61571
+ if (/^\s*RUN\b.*--mount=/im.test(logical)) throw new Error("\u5E95\u5EA7\u6302\u8F7D\u8F93\u5165\u65E0\u6CD5\u5B8C\u6574\u6BD4\u8F83\uFF0C\u8BF7\u91CD\u65B0\u6784\u5EFA");
61572
+ const inputs = /* @__PURE__ */ new Set([DOCKERFILE, "cloud-host/.dockerignore", "cloud-host/Dockerfile.base.dockerignore"]);
61573
+ for (const line of logical.split("\n")) {
61574
+ const instruction = /^\s*(?:COPY|ADD)\s+(.+)$/i.exec(line)?.[1];
61575
+ if (!instruction || /^--from=\S+\s/.test(instruction)) continue;
61576
+ const tokens = instruction.startsWith("[") ? JSON.parse(instruction) : instruction.trim().split(/\s+/);
61577
+ if (!Array.isArray(tokens) || tokens.length < 2) throw new Error("\u5E95\u5EA7 COPY \u8F93\u5165\u4E0D\u5B8C\u6574\uFF0C\u8BF7\u91CD\u65B0\u6784\u5EFA");
61578
+ for (const source of tokens.slice(0, -1)) {
61579
+ if (typeof source !== "string" || !/^[A-Za-z0-9_-][A-Za-z0-9_./-]*$/.test(source) || source.split("/").some((segment) => !segment || segment === "." || segment === "..")) {
61580
+ throw new Error("\u5E95\u5EA7 COPY \u8F93\u5165\u65E0\u6CD5\u5B8C\u6574\u6BD4\u8F83\uFF0C\u8BF7\u91CD\u65B0\u6784\u5EFA");
61581
+ }
61582
+ inputs.add("cloud-host/" + source.replace(/\/$/, ""));
61583
+ }
61584
+ }
61585
+ return inputs;
61586
+ }
61517
61587
  async function readCurrentBase(api) {
61518
61588
  const current = await currentSource(api);
61519
61589
  const listed = await api.getJsonStrict(`/repos/${SLUG}/actions/workflows/base-image-acr.yml/runs?branch=release&per_page=1`);
@@ -61535,10 +61605,23 @@ async function readCurrentBase(api) {
61535
61605
  const parsed = BaseSchema.safeParse(await readReleaseArchive(await api.downloadArtifact(SLUG, artifact.id)));
61536
61606
  if (!parsed.success) throw new Error("\u5E95\u5EA7\u5236\u54C1\u7248\u672C\u8BB0\u5F55\u65E0\u6548\uFF0C\u8BF7\u91CD\u65B0\u8FD0\u884C\u5E95\u5EA7\u6784\u5EFA");
61537
61607
  const release2 = parsed.data;
61538
- const matches = (source) => release2.source.cloudHost === source.cloudHost && release2.source.workflow === source.workflow;
61539
- if (release2.workflowCommit !== run.head_sha || !matches(current.source)) throw new Error("\u5E95\u5EA7\u5C1A\u672A\u6784\u5EFA\u5F53\u524D release \u6E90\u7801\uFF0C\u8BF7\u7B49\u5F85\u6216\u91CD\u65B0\u8FD0\u884C\u5E95\u5EA7\u6D41\u6C34\u7EBF");
61608
+ const matches = async (candidate) => {
61609
+ if (release2.source.workflow !== candidate.source.workflow) return false;
61610
+ if (release2.source.cloudHost === candidate.source.cloudHost) return true;
61611
+ if (release2.commit === candidate.commit) return false;
61612
+ const comparison = await api.getJsonStrict(`/repos/${SLUG}/compare/${release2.commit}...${candidate.commit}`);
61613
+ if (comparison.status !== "ahead" || !Array.isArray(comparison.files) || comparison.files.length >= 300 || comparison.files.some((file) => typeof file.filename !== "string" || !file.filename)) {
61614
+ throw new Error("\u65E0\u6CD5\u5B8C\u6574\u6BD4\u8F83\u5E95\u5EA7\u8F93\u5165\uFF0C\u8BF7\u91CD\u65B0\u8FD0\u884C\u5E95\u5EA7\u6D41\u6C34\u7EBF");
61615
+ }
61616
+ if (comparison.files.some((file) => file.filename === DOCKERFILE || file.previous_filename === DOCKERFILE)) return false;
61617
+ const recipe = await api.getJsonStrict(`/repos/${SLUG}/contents/${DOCKERFILE}?ref=${candidate.commit}`);
61618
+ if (recipe.type !== "file" || recipe.encoding !== "base64" || typeof recipe.content !== "string") throw new Error("\u8BFB\u4E0D\u5230\u5E95\u5EA7\u6784\u5EFA\u914D\u65B9");
61619
+ const inputs = dockerfileInputs(Buffer.from(recipe.content, "base64").toString("utf8"));
61620
+ return comparison.files.every((file) => ![file.filename, file.previous_filename].some((filename) => filename && [...inputs].some((input) => filename === input || filename.startsWith(input + "/"))));
61621
+ };
61622
+ if (release2.commit !== run.head_sha || release2.workflowCommit !== run.head_sha || !await matches(current)) throw new Error("\u5E95\u5EA7\u5C1A\u672A\u6784\u5EFA\u5F53\u524D release \u6E90\u7801\uFF0C\u8BF7\u7B49\u5F85\u6216\u91CD\u65B0\u8FD0\u884C\u5E95\u5EA7\u6D41\u6C34\u7EBF");
61540
61623
  const after = await currentSource(api);
61541
- if (!matches(after.source)) throw new Error("\u5E95\u5EA7\u6E90\u7801\u5728\u53D1\u5E03\u51C6\u5907\u671F\u95F4\u53D8\u5316\uFF0C\u8BF7\u7B49\u65B0\u6784\u5EFA\u6210\u529F\u540E\u518D\u53D1\u5E03");
61624
+ if ((after.source.cloudHost !== current.source.cloudHost || after.source.workflow !== current.source.workflow) && !await matches(after)) throw new Error("\u5E95\u5EA7\u6E90\u7801\u5728\u53D1\u5E03\u51C6\u5907\u671F\u95F4\u53D8\u5316\uFF0C\u8BF7\u7B49\u65B0\u6784\u5EFA\u6210\u529F\u540E\u518D\u53D1\u5E03");
61542
61625
  return release2;
61543
61626
  }
61544
61627
 
@@ -69396,25 +69479,12 @@ var EXTENSIONS_IMPORT_CORS_HEADERS = {
69396
69479
  "Access-Control-Allow-Headers": "Authorization, Content-Type",
69397
69480
  "Access-Control-Max-Age": "86400"
69398
69481
  };
69399
- var UPLOAD_MIME_ALLOW = /* @__PURE__ */ new Set([
69400
- "image/png",
69401
- "image/jpeg",
69402
- "image/gif",
69403
- "image/webp",
69404
- "application/pdf"
69405
- ]);
69406
- var UPLOAD_MIME_ALLOW_PREFIX = ["text/"];
69407
- var UPLOAD_MAX_BYTES = 25 * 1024 * 1024;
69408
69482
  var UPLOAD_CORS_HEADERS = {
69409
69483
  "Access-Control-Allow-Origin": "*",
69410
69484
  "Access-Control-Allow-Methods": "POST, OPTIONS",
69411
69485
  "Access-Control-Allow-Headers": "Authorization, Content-Type",
69412
69486
  "Access-Control-Max-Age": "86400"
69413
69487
  };
69414
- function isUploadMimeAllowed(mime) {
69415
- if (UPLOAD_MIME_ALLOW.has(mime)) return true;
69416
- return UPLOAD_MIME_ALLOW_PREFIX.some((p3) => mime.startsWith(p3));
69417
- }
69418
69488
  function isValidUploadFileName(fileName) {
69419
69489
  if (fileName.length === 0) return false;
69420
69490
  if (fileName === "." || fileName === "..") return false;
@@ -69695,14 +69765,15 @@ function createHttpRouter(deps) {
69695
69765
  sendUploadJson(400, { code: "INVALID_PARAM", message: "malformed Content-Length" });
69696
69766
  return true;
69697
69767
  }
69698
- if (contentLength > UPLOAD_MAX_BYTES) {
69768
+ if (contentLength > MAX_ATTACHMENT_BYTES) {
69699
69769
  sendUploadJson(413, {
69700
69770
  code: "FILE_TOO_LARGE",
69701
- message: `max ${UPLOAD_MAX_BYTES} bytes`
69771
+ message: `max ${MAX_ATTACHMENT_BYTES} bytes`
69702
69772
  });
69703
69773
  return true;
69704
69774
  }
69705
- if (!isUploadMimeAllowed(mimeType)) {
69775
+ const resolvedMime = resolveAttachmentUploadMime(fileName, mimeType);
69776
+ if (!resolvedMime) {
69706
69777
  sendUploadJson(400, {
69707
69778
  code: "UNSUPPORTED_MIME",
69708
69779
  message: `mime ${mimeType} not allowed`
@@ -69737,7 +69808,7 @@ function createHttpRouter(deps) {
69737
69808
  sessionId,
69738
69809
  scope,
69739
69810
  fileName,
69740
- mimeType,
69811
+ mimeType: resolvedMime,
69741
69812
  contentLength,
69742
69813
  body: req,
69743
69814
  groupFileStore: up.groupFileStore
@@ -74335,7 +74406,7 @@ function computeMethodAccess(args) {
74335
74406
  }
74336
74407
 
74337
74408
  // src/version.ts
74338
- var version = "0.2.648".length > 0 ? "0.2.648" : "dev";
74409
+ var version = "0.2.650".length > 0 ? "0.2.650" : "dev";
74339
74410
 
74340
74411
  // src/cli-probe/probe.ts
74341
74412
  var fs85 = __toESM(require("fs"), 1);