chatccc 0.2.217 → 0.2.218

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chatccc",
3
- "version": "0.2.217",
3
+ "version": "0.2.218",
4
4
  "description": "Feishu bot bridge for Claude Code",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -251,14 +251,14 @@ describe("Codex avatar usage battery", () => {
251
251
  const cacheRaw = await readFile(join(userDataDir, "state", "avatar-image-keys.json"), "utf-8");
252
252
  const cache = JSON.parse(cacheRaw) as Record<string, string>;
253
253
  expect(cache["codex:idle:plain"]).toBe("img_test");
254
- expect(cache["codex:idle:plain:fast-champagne-frame-v1"]).toBe("img_test");
254
+ expect(cache["codex:idle:plain:fast-champagne-frame-v2"]).toBe("img_test");
255
255
  } finally {
256
256
  await rm(homeDir, { recursive: true, force: true });
257
257
  await rm(userDataDir, { recursive: true, force: true });
258
258
  }
259
259
  });
260
260
 
261
- it("renders a thick champagne frame above the Codex badge in Fast mode", async () => {
261
+ it("renders an extra-thick champagne frame above the Codex badge in Fast mode", async () => {
262
262
  const homeDir = await mkdtemp(join(tmpdir(), "chatccc-avatar-home-"));
263
263
  const userDataDir = await mkdtemp(join(tmpdir(), "chatccc-avatar-data-"));
264
264
  const uploadedNames: string[] = [];
@@ -274,7 +274,7 @@ describe("Codex avatar usage battery", () => {
274
274
 
275
275
  expect(uploadedNames).toEqual(["avatar_codex_idle_fast.jpg"]);
276
276
  const { data, info } = await sharp(uploadedImages[0]).raw().toBuffer({ resolveWithObject: true });
277
- const pixelOffset = (149 * info.width + 200) * info.channels;
277
+ const pixelOffset = (144 * info.width + 200) * info.channels;
278
278
  const [red, green, blue] = data.subarray(pixelOffset, pixelOffset + 3);
279
279
  expect(red).toBeGreaterThan(220);
280
280
  expect(green).toBeGreaterThan(150);
package/src/feishu-api.ts CHANGED
@@ -324,7 +324,7 @@ const AVATAR_BADGE_SIZE = 92;
324
324
  const AVATAR_BADGE_MARGIN = 10;
325
325
  const PLAIN_AVATAR_TOOL = "plain";
326
326
  const CODEX_AVATAR_USAGE_STYLE_VERSION = "usage-window-aware-v14";
327
- const CODEX_FAST_FRAME_STYLE_VERSION = "fast-champagne-frame-v1";
327
+ const CODEX_FAST_FRAME_STYLE_VERSION = "fast-champagne-frame-v2";
328
328
  const CURSOR_AVATAR_USAGE_STYLE_VERSION = "usage-battery-v1";
329
329
 
330
330
  export interface CodexUsageBalance {
@@ -760,7 +760,10 @@ function buildCodexUsageRingSvg(remainingPercent: number): Buffer {
760
760
  </svg>`);
761
761
  }
762
762
 
763
- async function buildAgentBadgeOverlay(tool: string): Promise<sharp.OverlayOptions> {
763
+ async function buildAgentBadgeOverlay(
764
+ tool: string,
765
+ margin = AVATAR_BADGE_MARGIN,
766
+ ): Promise<sharp.OverlayOptions> {
764
767
  const badge = await sharp(AVATAR_BADGES[tool])
765
768
  .resize(AVATAR_BADGE_SIZE, AVATAR_BADGE_SIZE, {
766
769
  fit: "contain",
@@ -771,14 +774,14 @@ async function buildAgentBadgeOverlay(tool: string): Promise<sharp.OverlayOption
771
774
  .toBuffer();
772
775
  return {
773
776
  input: badge,
774
- left: AVATAR_SIZE - AVATAR_BADGE_SIZE - AVATAR_BADGE_MARGIN,
775
- top: AVATAR_SIZE - AVATAR_BADGE_SIZE - AVATAR_BADGE_MARGIN,
777
+ left: AVATAR_SIZE - AVATAR_BADGE_SIZE - margin,
778
+ top: AVATAR_SIZE - AVATAR_BADGE_SIZE - margin,
776
779
  };
777
780
  }
778
781
 
779
782
  function buildCodexFastFrameOverlay(): sharp.OverlayOptions {
780
- const size = AVATAR_BADGE_SIZE + 16;
781
- const innerOffset = 7;
783
+ const size = AVATAR_BADGE_SIZE + 20;
784
+ const innerOffset = 9;
782
785
  const innerSize = size - innerOffset * 2;
783
786
  const frame = Buffer.from(`
784
787
  <svg width="${size}" height="${size}" xmlns="http://www.w3.org/2000/svg">
@@ -794,8 +797,8 @@ function buildCodexFastFrameOverlay(): sharp.OverlayOptions {
794
797
  </svg>`);
795
798
  return {
796
799
  input: frame,
797
- left: AVATAR_SIZE - size - 2,
798
- top: AVATAR_SIZE - size - 2,
800
+ left: AVATAR_SIZE - size - 1,
801
+ top: AVATAR_SIZE - size - 1,
799
802
  };
800
803
  }
801
804
 
@@ -833,7 +836,7 @@ async function renderAvatar(
833
836
 
834
837
  if (useDynamicBadgeAvatar) {
835
838
  if (useFastCodexAvatar) composites.push(buildCodexFastFrameOverlay());
836
- composites.push(await buildAgentBadgeOverlay(normalizedTool));
839
+ composites.push(await buildAgentBadgeOverlay(normalizedTool, useFastCodexAvatar ? 11 : AVATAR_BADGE_MARGIN));
837
840
  }
838
841
 
839
842
  let pipeline = sharp(await readFile(basePath))