codebee 0.1.69 → 0.1.70

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 (57) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +4 -3
  3. package/app/browser-final-1440.png +0 -0
  4. package/app/browser-final-390.png +0 -0
  5. package/app/browser-google-fallback.png +0 -0
  6. package/app/browser-google-test.png +0 -0
  7. package/app/browser-workbench-1440.png +0 -0
  8. package/app/browser-workbench-390.png +0 -0
  9. package/app/browser-workspace-google.png +0 -0
  10. package/app/browser-workspace-smoke.png +0 -0
  11. package/app/browser-workspace.png +0 -0
  12. package/app/core/audit.py +30 -0
  13. package/app/core/automation.py +107 -12
  14. package/app/core/benchstore.py +95 -0
  15. package/app/core/bookmeta.py +9 -4
  16. package/app/core/builtin_agent.py +472 -33
  17. package/app/core/catalog.py +7 -1
  18. package/app/core/dispatch.py +20 -3
  19. package/app/core/error_codes.py +11 -2
  20. package/app/core/evalbench.py +720 -0
  21. package/app/core/flows.py +228 -3
  22. package/app/core/jobs.py +22 -1
  23. package/app/core/manager.py +21 -0
  24. package/app/core/market_remote.py +10 -0
  25. package/app/core/mcp_client.py +287 -0
  26. package/app/core/modelhub.py +185 -2
  27. package/app/core/notify.py +118 -23
  28. package/app/core/novel_quality.py +189 -0
  29. package/app/core/paths.py +4 -0
  30. package/app/core/pipeline.py +426 -28
  31. package/app/core/planner.py +243 -22
  32. package/app/core/plugins.py +525 -0
  33. package/app/core/publish/browser.py +129 -13
  34. package/app/core/publish/fanqie.py +6 -0
  35. package/app/core/publish/flow.py +154 -5
  36. package/app/core/publish/flows-fanqie-calibrated.json +11 -7
  37. package/app/core/publish/ledger.py +29 -3
  38. package/app/core/publish/manager.py +134 -2
  39. package/app/core/publish/qimao.py +5 -0
  40. package/app/core/remotesync.py +121 -0
  41. package/app/core/runner.py +80 -5
  42. package/app/core/settings.py +39 -2
  43. package/app/core/settings_schema.py +8 -0
  44. package/app/core/store.py +30 -8
  45. package/app/core/usage.py +187 -14
  46. package/app/core/zentao.py +153 -4
  47. package/app/current-browser.png +0 -0
  48. package/app/main.py +279 -15
  49. package/app/mcp_server.py +175 -0
  50. package/app/pet.py +82 -21
  51. package/app/plugins/code-review-helper/.codex-plugin/plugin.json +18 -0
  52. package/app/plugins/code-review-helper/skills/review.md +16 -0
  53. package/app/ui/app.js +1380 -73
  54. package/app/ui/i18n.js +248 -6
  55. package/app/ui/index.html +277 -13
  56. package/app/ui/style.css +786 -0
  57. package/package.json +2 -1
package/app/pet.py CHANGED
@@ -11,6 +11,10 @@ CodeBee 蜜蜂。实现要点:
11
11
  庆祝=原地旋转、睡觉=调暗降饱和、失联=灰化);机器没有 Pillow 或素材缺失
12
12
  时回落「手绘模式」——canvas 矢量卡通蜜蜂(零依赖兜底,npm 分发用户可能
13
13
  装不了 PIL)。
14
+ - 底板:Windows 用 -transparentcolor 键色逐像素透明,蜜蜂真浮空;macOS 的
15
+ Tk 没有逐像素透明(键色是 Windows 专属),矩形底板必然整个露出来还带
16
+ 系统边框——非 Windows 把底板画成深色卡片(「桌面小组件」形态),状态
17
+ 滤镜只作用于蜂体、不碰底板色(2026-09-25 Mac 实拍白板翻车)。
14
18
  - 状态机:sleep(打盹)/ work(振翅)/ cheer(翻滚庆祝)/ alert(警示抖动),
15
19
  由「上一轮活跃任务集合 vs 本轮结果」的差分推出,不需要后端记事件流。
16
20
  - 悬停任务清单走指针轮询而不是 Enter/Leave:-transparentcolor 的透明像素在
@@ -310,6 +314,72 @@ def _http_json(port, path, body=None):
310
314
  # 用罕见深色,蜜蜂配色不会撞上。
311
315
  KEY = "#010203"
312
316
  KEY_RGB = (1, 2, 3)
317
+ # 非 Windows 底板:macOS 的 Tk 没有逐像素透明(-transparentcolor 是
318
+ # Windows 专属),矩形底板必然整个露出来还带系统边框——索性把底板画成
319
+ # 深色卡片(对齐悬停清单面板色),桌宠呈「桌面小组件」形态,而不是
320
+ # 一块突兀的白板(2026-09-25 Mac 实拍翻车)。
321
+ CARD_BG = "#1B2430"
322
+ CARD_RGB = (27, 36, 48)
323
+
324
+
325
+ def plate_for(os_name):
326
+ """底板色:Windows=键色(配 -transparentcolor 逐像素透明);其余=卡片色。"""
327
+ return KEY if os_name == "nt" else CARD_BG
328
+
329
+
330
+ def plate_rgb_for(os_name):
331
+ """底板色的 RGB 元组(精灵帧合成/噪点归底用),与 plate_for 同源。"""
332
+ return KEY_RGB if os_name == "nt" else CARD_RGB
333
+
334
+
335
+ PLATE = plate_for(os.name)
336
+ PLATE_RGB = plate_rgb_for(os.name)
337
+
338
+
339
+ def composite_plate(img, plate_rgb):
340
+ """RGBA 精灵合成到不透明底色(纯像素逻辑,不碰 Tk,可测试)。"""
341
+ from PIL import Image
342
+ bg = Image.new("RGBA", img.size, tuple(plate_rgb) + (255,))
343
+ bg.alpha_composite(img)
344
+ return bg.convert("RGB")
345
+
346
+
347
+ def knock_to_plate(img, plate_rgb):
348
+ """近底色噪点(旋转/缩放的 AA 碎点)归底色,原地修改并返回。"""
349
+ pr, pg, pb = plate_rgb
350
+ px = img.load()
351
+ w, h = img.size
352
+ for yy in range(h):
353
+ for xx in range(w):
354
+ r, g, b = px[xx, yy]
355
+ if abs(r - pr) + abs(g - pg) + abs(b - pb) < 12:
356
+ px[xx, yy] = plate_rgb
357
+ return img
358
+
359
+
360
+ def mood_rgba(img, color=1.0, bright=1.0):
361
+ """状态滤镜(降饱和/调暗/灰化)只作用于有内容的像素,底板色不动。
362
+
363
+ ImageEnhance 系列对整图混色,会把透明洞当黑色往里掺;而本文件的做法
364
+ 是先合成到底板再出帧,底板跟着变暗后卡片上就浮出一块更暗的小框
365
+ (Windows 靠近键噪点归键兜回来,Mac 卡片底兜不回来)——故按 alpha
366
+ 手做:透明像素原样,蜂体像素做 luma 降饱和 + 调暗。不修改入参图。
367
+ """
368
+ img = img.copy()
369
+ px = img.load()
370
+ w, h = img.size
371
+ for yy in range(h):
372
+ for xx in range(w):
373
+ r, g, b, a = px[xx, yy]
374
+ if not a:
375
+ continue
376
+ lum = int(r * 0.299 + g * 0.587 + b * 0.114)
377
+ px[xx, yy] = (
378
+ min(255, max(0, int((lum * (1 - color) + r * color) * bright))),
379
+ min(255, max(0, int((lum * (1 - color) + g * color) * bright))),
380
+ min(255, max(0, int((lum * (1 - color) + b * color) * bright))),
381
+ a)
382
+ return img
313
383
  WIN_W, WIN_H = 170, 150 # 手绘回落模式的窗口尺寸
314
384
  SPRITE_DIR = Path(__file__).resolve().parent
315
385
  SPRITE_DISP_H = 112 # 精灵显示高度(宽等比)
@@ -496,7 +566,7 @@ class PetApp:
496
566
  self.root.attributes("-transparentcolor", KEY)
497
567
  except Exception:
498
568
  pass
499
- self.root.configure(bg=KEY)
569
+ self.root.configure(bg=PLATE)
500
570
 
501
571
  # 形象:本地 cfg 优先(换形象要立刻见效,不等服务端轮询),缺省 plush
502
572
  self.skin = str(cfg.get("skin") or DEFAULT_SKIN)
@@ -515,7 +585,7 @@ class PetApp:
515
585
  self.win_w, self.win_h = WIN_W, WIN_H
516
586
 
517
587
  self.cv = tk.Canvas(self.root, width=self.win_w, height=self.win_h,
518
- bg=KEY, highlightthickness=0, bd=0)
588
+ bg=PLATE, highlightthickness=0, bd=0)
519
589
  self.cv.pack()
520
590
  self.spr = None
521
591
 
@@ -628,7 +698,7 @@ class PetApp:
628
698
  expand 放画布,窗口会比蜂体大一圈,点缀画件全悬空(真机截图翻车)。
629
699
  """
630
700
  try:
631
- from PIL import Image, ImageEnhance, ImageTk
701
+ from PIL import Image, ImageTk
632
702
  except Exception:
633
703
  # 无 Pillow:用 Tk 原生 PhotoImage 直接贴 PNG(Tk 8.6+ 原生解码,
634
704
  # 零依赖)——此前直接回落手绘蜂,普通用户 npm 装完没有 Pillow,
@@ -659,30 +729,21 @@ class PetApp:
659
729
  base = base0.resize((disp_w, disp_h), Image.LANCZOS)
660
730
 
661
731
  def flat(img):
662
- """合成到键色底:羽化边缘自然过渡,键色即透明,无需真 alpha。"""
663
- bg = Image.new("RGBA", img.size, KEY_RGB + (255,))
664
- bg.alpha_composite(img)
665
- return bg.convert("RGB")
732
+ """合成到底板色:Windows 键色待逐像素透明,Mac 卡片底;
733
+ 羽化边缘自然过渡,无需真 alpha。"""
734
+ return composite_plate(img, PLATE_RGB)
666
735
 
667
736
  def bake(img):
668
- """RGB → PhotoImage;近键色噪点(旋转/缩放的 AA 碎点)归键。"""
669
- px = img.load()
670
- w, h = img.size
671
- for yy in range(h):
672
- for xx in range(w):
673
- r, g, b = px[xx, yy]
674
- if abs(r - 1) + abs(g - 2) + abs(b - 3) < 12:
675
- px[xx, yy] = KEY_RGB
676
- return ImageTk.PhotoImage(img)
737
+ """RGB → PhotoImage;近底色噪点(旋转/缩放的 AA 碎点)归底。"""
738
+ return ImageTk.PhotoImage(knock_to_plate(img, PLATE_RGB))
677
739
 
678
740
  rot = lambda a: flat(base.rotate(a, resample=Image.BICUBIC))
679
741
  frames = {
680
742
  "alert": [bake(flat(base))],
681
- "sleep": [bake(ImageEnhance.Brightness(
682
- ImageEnhance.Color(flat(base)).enhance(0.7)
683
- ).enhance(0.55))],
684
- "dead": [bake(ImageEnhance.Brightness(
685
- flat(base).convert("L").convert("RGB")).enhance(0.6))],
743
+ # 睡觉降饱和调暗 / 失联灰化:滤镜只碰蜂体不碰底板
744
+ # (mood_rgba 按 alpha 手做,底板色恒定,卡片不浮暗框)
745
+ "sleep": [bake(flat(mood_rgba(base, color=0.7, bright=0.55)))],
746
+ "dead": [bake(flat(mood_rgba(base, color=0.0, bright=0.6)))],
686
747
  "work": [bake(rot(a)) for a in (-8, -4, 0, 4, 8)],
687
748
  # 欢腾摇摆:左倾-回正-右倾-回正,像跳舞不像旋转木马
688
749
  "cheer": [bake(rot(a)) for a in (0, 10, 20, 10, 0, -10,
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "code-review-helper",
3
+ "version": "0.1.0",
4
+ "description": "把代码评审前的风险检查接入 CodeBee。",
5
+ "author": {
6
+ "name": "CodeBee"
7
+ },
8
+ "skills": "./skills/",
9
+ "interface": {
10
+ "displayName": "代码评审助手",
11
+ "shortDescription": "提测前快速检查边界、异常、并发与安全风险。",
12
+ "longDescription": "一个轻量的代码评审守则插件,安装后会在 code 类型任务中自动注入检查清单。",
13
+ "developerName": "CodeBee",
14
+ "category": "代码开发",
15
+ "capabilities": ["Review", "Write"],
16
+ "defaultPrompt": ["请按评审清单检查这段代码。"]
17
+ }
18
+ }
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: 代码评审助手
3
+ scopes:
4
+ - code
5
+ note: 提测前检查边界、异常、并发与安全风险
6
+ ---
7
+
8
+ # 代码评审助手
9
+
10
+ 在提交评审前,按下面顺序检查并给出证据:
11
+
12
+ 1. 输入边界:空值、超长值、非法状态和权限边界是否有明确行为。
13
+ 2. 异常路径:失败是否可观察、可重试,是否会吞掉错误或留下半成品。
14
+ 3. 并发与资源:共享状态、锁、超时、子进程和临时文件是否能收敛。
15
+ 4. 安全:路径穿越、命令注入、凭据泄漏和不可信内容注入是否被阻断。
16
+ 5. 回归:为每个修复点补一个最小测试,并说明没有覆盖的风险。