@neta-art/cohub-cli 3.9.0 → 3.9.2

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/avatar.d.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  import type { CohubHttpClient, PublicAssetPurpose } from "@neta-art/cohub";
2
- export declare function normalizeAvatarFile(path: string): Promise<Buffer>;
2
+ type PreparedAvatar = {
3
+ body: Buffer;
4
+ mimeType: "image/webp" | "image/jpeg" | "image/png" | "image/gif";
5
+ extension: "webp" | "jpg" | "png" | "gif";
6
+ };
7
+ export declare function normalizeAvatarFile(path: string): Promise<PreparedAvatar>;
3
8
  export declare function uploadAvatarAsset(input: {
4
9
  client: CohubHttpClient;
5
10
  purpose: PublicAssetPurpose;
@@ -40,3 +45,4 @@ export declare function uploadChatImageAsset(input: {
40
45
  uploadHeaders?: Record<string, string>;
41
46
  size: number;
42
47
  }>;
48
+ export {};
package/dist/avatar.js CHANGED
@@ -1,21 +1,49 @@
1
+ import { readFile } from "node:fs/promises";
1
2
  import sharp from "sharp";
2
3
  const AVATAR_SIZE = 1024;
3
4
  const AVATAR_QUALITY = 86;
5
+ const detectAvatarFormat = (body) => {
6
+ if (body.subarray(0, 3).equals(Buffer.from([0xff, 0xd8, 0xff]))) {
7
+ return { mimeType: "image/jpeg", extension: "jpg" };
8
+ }
9
+ if (body.subarray(0, 8).equals(Buffer.from("89504e470d0a1a0a", "hex"))) {
10
+ return { mimeType: "image/png", extension: "png" };
11
+ }
12
+ if (body.subarray(0, 6).toString("ascii") === "GIF87a" || body.subarray(0, 6).toString("ascii") === "GIF89a") {
13
+ return { mimeType: "image/gif", extension: "gif" };
14
+ }
15
+ if (body.subarray(0, 4).toString("ascii") === "RIFF" && body.subarray(8, 12).toString("ascii") === "WEBP") {
16
+ return { mimeType: "image/webp", extension: "webp" };
17
+ }
18
+ return null;
19
+ };
4
20
  export async function normalizeAvatarFile(path) {
5
- return sharp(path)
6
- .rotate()
7
- .resize(AVATAR_SIZE, AVATAR_SIZE, { fit: "cover", position: "centre" })
8
- .webp({ quality: AVATAR_QUALITY })
9
- .toBuffer();
21
+ const original = await readFile(path);
22
+ const originalFormat = detectAvatarFormat(original);
23
+ if (!originalFormat)
24
+ throw new Error("Avatar must be a JPEG, PNG, GIF, or WebP image");
25
+ if (originalFormat.mimeType === "image/gif")
26
+ return { body: original, ...originalFormat };
27
+ try {
28
+ const body = await sharp(original)
29
+ .rotate()
30
+ .resize(AVATAR_SIZE, AVATAR_SIZE, { fit: "cover", position: "centre" })
31
+ .webp({ quality: AVATAR_QUALITY })
32
+ .toBuffer();
33
+ return { body, mimeType: "image/webp", extension: "webp" };
34
+ }
35
+ catch {
36
+ return { body: original, ...originalFormat };
37
+ }
10
38
  }
11
39
  export async function uploadAvatarAsset(input) {
12
- const body = await normalizeAvatarFile(input.path);
40
+ const avatar = await normalizeAvatarFile(input.path);
13
41
  return input.client.publicAssets.upload({
14
42
  purpose: input.purpose,
15
43
  spaceId: input.spaceId,
16
- file: new Blob([new Uint8Array(body)], { type: "image/webp" }),
17
- mimeType: "image/webp",
18
- filename: "avatar.webp",
44
+ file: new Blob([new Uint8Array(avatar.body)], { type: avatar.mimeType }),
45
+ mimeType: avatar.mimeType,
46
+ filename: `avatar.${avatar.extension}`,
19
47
  });
20
48
  }
21
49
  const CHAT_IMAGE_MAX_EDGE = 1984;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neta-art/cohub-cli",
3
- "version": "3.9.0",
3
+ "version": "3.9.2",
4
4
  "description": "CLI for Cohub — spaces, sessions, and agent collaboration.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -19,7 +19,7 @@
19
19
  "commander": "^15.0.0",
20
20
  "pixi.js": "^8.19.0",
21
21
  "sharp": "^0.35.3",
22
- "@neta-art/cohub": "5.4.1"
22
+ "@neta-art/cohub": "5.4.3"
23
23
  },
24
24
  "publishConfig": {
25
25
  "access": "public"