From 296b1466ef1d3f7ad73279cae80960465753c590 Mon Sep 17 00:00:00 2001 From: karuo Date: Wed, 11 Mar 2026 14:45:52 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=84=20=E5=8D=A1=E8=8B=A5AI=20=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=202026-03-11=2014:45=20|=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=EF=BC=9A=E5=8D=A1=E6=9C=A8=E3=80=81=E8=BF=90=E8=90=A5=E4=B8=AD?= =?UTF-8?q?=E6=9E=A2=E5=B7=A5=E4=BD=9C=E5=8F=B0=20|=20=E6=8E=92=E9=99=A4?= =?UTF-8?q?=20>20MB:=2011=20=E4=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../视频切片/参考资料/LTX_能力与集成说明.md | 85 +++++++++++-------- .../木叶_视频内容/视频切片/脚本/visual_enhance.py | 82 +++++++++++------- 运营中枢/工作台/gitea_push_log.md | 1 + 运营中枢/工作台/代码管理.md | 1 + 4 files changed, 102 insertions(+), 67 deletions(-) diff --git a/03_卡木(木)/木叶_视频内容/视频切片/参考资料/LTX_能力与集成说明.md b/03_卡木(木)/木叶_视频内容/视频切片/参考资料/LTX_能力与集成说明.md index fe9c61fd..c6af33b9 100644 --- a/03_卡木(木)/木叶_视频内容/视频切片/参考资料/LTX_能力与集成说明.md +++ b/03_卡木(木)/木叶_视频内容/视频切片/参考资料/LTX_能力与集成说明.md @@ -7,14 +7,16 @@ ## 一、LTX 生态概览 -| 项目 | 仓库 | 能力摘要 | -|------|------|----------| -| **LTX-Video** | [Lightricks/LTX-Video](https://github.com/Lightricks/LTX-Video) | DiT 视频生成:图/文/视频→视频、关键帧动画、视频前后扩展、Video-to-Video;ComfyUI/Diffusers;Prompt 增强 | -| **LTX-2** | [Lightricks/LTX-2](https://github.com/Lightricks/LTX-2) | **音视频同步生成**、4K、多关键帧、**RetakePipeline**(重生成某段时间)、A2V、LoRA/IC-LoRA | + +| 项目 | 仓库 | 能力摘要 | +| --------------- | ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| **LTX-Video** | [Lightricks/LTX-Video](https://github.com/Lightricks/LTX-Video) | DiT 视频生成:图/文/视频→视频、关键帧动画、视频前后扩展、Video-to-Video;ComfyUI/Diffusers;Prompt 增强 | +| **LTX-2** | [Lightricks/LTX-2](https://github.com/Lightricks/LTX-2) | **音视频同步生成**、4K、多关键帧、**RetakePipeline**(重生成某段时间)、A2V、LoRA/IC-LoRA | | **LTX Desktop** | [audiohacking/LTX-Desktop-MPS](https://github.com/audiohacking/LTX-Desktop-MPS) | 桌面应用,**Text/Image/Audio to video**、**Video edit (Retake)**、编辑器界面;支持 Apple MPS 本地推理 | -**文档**:https://docs.ltx.video -**在线试玩**:https://app.ltx.studio(图生视频、工作流) + +**文档**:[https://docs.ltx.video](https://docs.ltx.video) +**在线试玩**:[https://app.ltx.studio(图生视频、工作流)](https://app.ltx.studio(图生视频、工作流)) --- @@ -22,29 +24,35 @@ ### 2.1 与「剪辑/成片」直接相关 -| 能力 | 说明 | 在切片 Skill 中的用途 | -|------|------|------------------------| -| **Retake(重剪)** | 对已有视频的**某一时间段**重新生成内容(LTX-2 RetakePipeline) | 在已有录播上「改一段」:替换口误、补拍、改台词段落,无需整片重录 | -| **Video extension** | 在视频**前/后**扩展帧(LTX-Video inference) | 片头/片尾自然延长、衔接下一段切片 | -| **Video-to-video** | 以原视频为条件做风格/内容变换(ICLoraPipeline 等) | 统一画风、去水印、风格化成片 | -| **多关键帧** | 多图/多段视频作为条件,控制生成内容 | 按「章节关键帧」生成过渡片段,再与现有切片拼接 | + +| 能力 | 说明 | 在切片 Skill 中的用途 | +| ------------------- | ------------------------------------------- | -------------------------------- | +| **Retake(重剪)** | 对已有视频的**某一时间段**重新生成内容(LTX-2 RetakePipeline) | 在已有录播上「改一段」:替换口误、补拍、改台词段落,无需整片重录 | +| **Video extension** | 在视频**前/后**扩展帧(LTX-Video inference) | 片头/片尾自然延长、衔接下一段切片 | +| **Video-to-video** | 以原视频为条件做风格/内容变换(ICLoraPipeline 等) | 统一画风、去水印、风格化成片 | +| **多关键帧** | 多图/多段视频作为条件,控制生成内容 | 按「章节关键帧」生成过渡片段,再与现有切片拼接 | + ### 2.2 AI 生成新内容(与切片流程衔接) -| 能力 | 说明 | 在切片 Skill 中的用途 | -|------|------|------------------------| -| **Text-to-video** | 文案/脚本 → 视频 | 用 AI 生成口播替代片段、片头片尾、插播小段 | -| **Image-to-video** | 首帧图 → 动起来 | 封面图/金句图 → 3~10 秒动效,再与切片合成 | -| **Audio-to-video** | 音频 → 口型/画面同步(LTX-2 A2V) | 用配音/旁白生成对应画面,补全缺失画面 | -| **Keyframe 插值** | 多张关键帧 → 中间过渡(KeyframeInterpolationPipeline) | 章节之间插过渡动画,成片更顺滑 | + +| 能力 | 说明 | 在切片 Skill 中的用途 | +| ------------------ | ------------------------------------------- | ------------------------- | +| **Text-to-video** | 文案/脚本 → 视频 | 用 AI 生成口播替代片段、片头片尾、插播小段 | +| **Image-to-video** | 首帧图 → 动起来 | 封面图/金句图 → 3~10 秒动效,再与切片合成 | +| **Audio-to-video** | 音频 → 口型/画面同步(LTX-2 A2V) | 用配音/旁白生成对应画面,补全缺失画面 | +| **Keyframe 插值** | 多张关键帧 → 中间过渡(KeyframeInterpolationPipeline) | 章节之间插过渡动画,成片更顺滑 | + ### 2.3 提升成片质量的通用能力 -| 能力 | 说明 | 在切片 Skill 中的用途 | -|------|------|------------------------| -| **自动 Prompt 增强** | 模型侧 `enhance_prompt=True` 或 LTX-Studio 自动增强 | 高光/标题文案 → 更易被生成模型理解的描述,便于做 I2V/Retake | -| **控制 LoRA** | 深度/姿态/Canny 等控制图 | 保持人物姿态、景深一致,成片更稳 | -| **ComfyUI 工作流** | 官方 [ComfyUI-LTXVideo](https://github.com/Lightricks/ComfyUI-LTXVideo) 节点与示例 | 可视化编排:转录/高光 → 生成片段 → 与 FFmpeg 切片/成片串联 | + +| 能力 | 说明 | 在切片 Skill 中的用途 | +| ---------------- | --------------------------------------------------------------------------- | ------------------------------------- | +| **自动 Prompt 增强** | 模型侧 `enhance_prompt=True` 或 LTX-Studio 自动增强 | 高光/标题文案 → 更易被生成模型理解的描述,便于做 I2V/Retake | +| **控制 LoRA** | 深度/姿态/Canny 等控制图 | 保持人物姿态、景深一致,成片更稳 | +| **ComfyUI 工作流** | 官方 [ComfyUI-LTXVideo](https://github.com/Lightricks/ComfyUI-LTXVideo) 节点与示例 | 可视化编排:转录/高光 → 生成片段 → 与 FFmpeg 切片/成片串联 | + --- @@ -79,11 +87,13 @@ ### 4.1 云端 API(零显存、快速接入) -| 服务 | 能力 | 说明 | -|------|------|------| -| **LTX-Studio** | 图生视频、工作流 | https://app.ltx.studio,在线用,可导出视频后本地切片 | -| **Fal.ai** | LTX-Video 13B 图生视频 | 见 [LTX-Video README](https://github.com/Lightricks/LTX-Video) Quick Start | -| **Replicate** | LTX-Video | 同上,按需调用 | + +| 服务 | 能力 | 说明 | +| -------------- | ------------------ | ------------------------------------------------------------------------------ | +| **LTX-Studio** | 图生视频、工作流 | [https://app.ltx.studio,在线用,可导出视频后本地切片](https://app.ltx.studio,在线用,可导出视频后本地切片) | +| **Fal.ai** | LTX-Video 13B 图生视频 | 见 [LTX-Video README](https://github.com/Lightricks/LTX-Video) Quick Start | +| **Replicate** | LTX-Video | 同上,按需调用 | + **与切片联动**:脚本内调用 API 得到 mp4 → 保存到指定目录 → 用现有 `batch_clip` / `soul_enhance` 或直接进 `成片/` 做封面字幕。 @@ -126,11 +136,14 @@ LTX 官方建议的 **Prompt 写法**(可直接用于「高光标题 → 生 ## 七、参考链接 -| 资源 | 链接 | -|------|------| -| LTX-Video 官方仓库 | https://github.com/Lightricks/LTX-Video | -| LTX-2 官方仓库(含 Retake) | https://github.com/Lightricks/LTX-2 | -| LTX Desktop (MPS) | https://github.com/audiohacking/LTX-Desktop-MPS | -| LTX 文档 | https://docs.ltx.video | -| ComfyUI-LTXVideo | https://github.com/Lightricks/ComfyUI-LTXVideo | -| LTX-Studio 在线 | https://app.ltx.studio | + +| 资源 | 链接 | +| -------------------- | -------------------------------------------------------------------------------------------------- | +| LTX-Video 官方仓库 | [https://github.com/Lightricks/LTX-Video](https://github.com/Lightricks/LTX-Video) | +| LTX-2 官方仓库(含 Retake) | [https://github.com/Lightricks/LTX-2](https://github.com/Lightricks/LTX-2) | +| LTX Desktop (MPS) | [https://github.com/audiohacking/LTX-Desktop-MPS](https://github.com/audiohacking/LTX-Desktop-MPS) | +| LTX 文档 | [https://docs.ltx.video](https://docs.ltx.video) | +| ComfyUI-LTXVideo | [https://github.com/Lightricks/ComfyUI-LTXVideo](https://github.com/Lightricks/ComfyUI-LTXVideo) | +| LTX-Studio 在线 | [https://app.ltx.studio](https://app.ltx.studio) | + + diff --git a/03_卡木(木)/木叶_视频内容/视频切片/脚本/visual_enhance.py b/03_卡木(木)/木叶_视频内容/视频切片/脚本/visual_enhance.py index 06edbd8b..5fcc41ed 100644 --- a/03_卡木(木)/木叶_视频内容/视频切片/脚本/visual_enhance.py +++ b/03_卡木(木)/木叶_视频内容/视频切片/脚本/visual_enhance.py @@ -54,13 +54,33 @@ CYAN = (34, 211, 238, 255) ACCENTS = [BLUE, PURPLE, GREEN, GOLD, ORANGE, RED, CYAN] -def font(size: int, bold: bool = False): - candidates = [ - FONTS_DIR / ('SourceHanSansSC-Heavy.otf' if bold else 'SourceHanSansSC-Bold.otf'), - FONTS_DIR / 'SourceHanSansSC-Bold.otf', - FONTS_DIR / 'NotoSansCJK-Bold.ttc', - Path('/System/Library/Fonts/PingFang.ttc'), - ] +def font(size: int, weight='medium'): + if isinstance(weight, bool): + weight = 'bold' if weight else 'medium' + font_map = { + 'regular': [ + FONTS_DIR / 'NotoSansCJK-Regular.ttc', + FONTS_DIR / 'SourceHanSansSC-Medium.otf', + Path('/System/Library/Fonts/PingFang.ttc'), + ], + 'medium': [ + FONTS_DIR / 'SourceHanSansSC-Medium.otf', + FONTS_DIR / 'NotoSansCJK-Regular.ttc', + Path('/System/Library/Fonts/PingFang.ttc'), + ], + 'semibold': [ + FONTS_DIR / 'SourceHanSansSC-Bold.otf', + FONTS_DIR / 'NotoSansCJK-Bold.ttc', + Path('/System/Library/Fonts/PingFang.ttc'), + ], + 'bold': [ + FONTS_DIR / 'SourceHanSansSC-Heavy.otf', + FONTS_DIR / 'SourceHanSansSC-Bold.otf', + FONTS_DIR / 'NotoSansCJK-Bold.ttc', + Path('/System/Library/Fonts/PingFang.ttc'), + ], + } + candidates = font_map.get(weight, font_map['medium']) for path in candidates: if path.exists(): try: @@ -175,7 +195,7 @@ def create_chip(text, accent, active=1.0): fill = (22, 28, 45, int(185 * active)) border = accent[:3] + (int(155 * active),) rounded(d, (0, 0, w - 1, h - 1), 17, fill=fill, outline=border, width=1) - ff = font(14, True) + ff = font(14, 'medium') bbox = ff.getbbox(text) tw = bbox[2] - bbox[0] th = bbox[3] - bbox[1] @@ -190,9 +210,9 @@ def create_metric_card(title, value, subtitle, accent, progress): fill = (18, 24, 38, 215) rounded(d, (0, 0, w - 1, h - 1), 18, fill=fill, outline=accent[:3] + (120,), width=1) d.rounded_rectangle((12, 14, 16, h - 14), radius=2, fill=accent[:3] + (220,)) - d.text((24, 12), title, font=font(11, True), fill=TEXT_SUB) - d.text((24, 34), value, font=font(22, True), fill=accent) - d.text((24, 60), subtitle, font=font(10), fill=TEXT_MUTED) + d.text((24, 12), title, font=font(11, 'medium'), fill=TEXT_SUB) + d.text((24, 34), value, font=font(21, 'medium'), fill=accent) + d.text((24, 60), subtitle, font=font(10, 'regular'), fill=TEXT_MUTED) dot_r = 5 + int(2 * math.sin(progress * math.pi * 2)) d.ellipse((w - 20 - dot_r, 12 - dot_r // 2, w - 20 + dot_r, 12 + dot_r), fill=accent[:3] + (200,)) return img @@ -289,8 +309,8 @@ def compose_panel(scene, scene_type, local_t, scene_progress): d = ImageDraw.Draw(base) rounded(d, (18, 16, 76, 40), 12, fill=(52, 211, 153, 210)) - d.text((30, 22), 'AI', font=font(12, True), fill=WHITE) - d.text((90, 22), '卡若式视频增强', font=font(12, True), fill=TEXT_SUB) + d.text((30, 22), 'AI', font=font(12, 'medium'), fill=WHITE) + d.text((90, 22), '卡若式视频增强', font=font(12, 'medium'), fill=TEXT_SUB) base.alpha_composite(create_video_window(scene_type, local_t), (PANEL_W - 158, 18)) if scene_type == 'title_card': @@ -299,13 +319,13 @@ def compose_panel(scene, scene_type, local_t, scene_progress): typed_ratio = ease_out_cubic(min(1.0, local_t / 1.9)) chars = max(1, int(len(question) * typed_ratio)) q_text = question[:chars] - draw_wrap(d, q_text, font(22, True), 230, 24, 74, WHITE) + draw_wrap(d, q_text, font(21, 'medium'), 230, 24, 74, WHITE) if typed_ratio < 1: cursor_x = 24 + min(230, int(typed_ratio * 230)) - d.text((cursor_x, 108), '▍', font=font(18, True), fill=BLUE) + d.text((cursor_x, 108), '▍', font=font(18, 'regular'), fill=BLUE) if local_t > 1.0: alpha = ease_out_cubic(min(1.0, (local_t - 1.0) / 1.0)) - d.text((24, 144), subtitle, font=font(14), fill=(TEXT_SUB[0], TEXT_SUB[1], TEXT_SUB[2], int(255 * alpha))) + d.text((24, 144), subtitle, font=font(14, 'regular'), fill=(TEXT_SUB[0], TEXT_SUB[1], TEXT_SUB[2], int(255 * alpha))) chip_texts = ['传统行业', '远程安装', '副业服务'] for i, txt in enumerate(chip_texts): ct = max(0.0, min(1.0, (local_t - 1.4 - i * 0.18) / 0.5)) @@ -314,22 +334,22 @@ def compose_panel(scene, scene_type, local_t, scene_progress): base.alpha_composite(chip, (24 + i * 96, 270 - int((1 - ct) * 14))) elif scene_type == 'comparison_card': params = scene['params'] - d.text((22, 70), params['title'], font=font(16, True), fill=WHITE) + d.text((22, 70), params['title'], font=font(15, 'medium'), fill=WHITE) rounded(d, (22, 102, 193, 286), 18, fill=(39, 19, 28, 200), outline=(248, 113, 113, 120), width=1) rounded(d, (205, 102, 396, 286), 18, fill=(18, 42, 31, 200), outline=(52, 211, 153, 120), width=1) - d.text((36, 116), params['left_title'], font=font(13, True), fill=RED) - d.text((220, 116), params['right_title'], font=font(13, True), fill=GREEN) + d.text((36, 116), params['left_title'], font=font(13, 'medium'), fill=RED) + d.text((220, 116), params['right_title'], font=font(13, 'medium'), fill=GREEN) for i, item in enumerate(params['left_items']): alpha = ease_out_cubic(min(1.0, max(0.0, (local_t - 0.4 - i * 0.15) / 0.5))) if alpha > 0: - d.text((34 - int((1 - alpha) * 14), 148 + i * 34), f'✕ {item}', font=font(13), fill=(248, 113, 113, int(220 * alpha))) + d.text((34 - int((1 - alpha) * 14), 148 + i * 34), f'✕ {item}', font=font(13, 'regular'), fill=(248, 113, 113, int(220 * alpha))) for i, item in enumerate(params['right_items']): alpha = ease_out_cubic(min(1.0, max(0.0, (local_t - 0.7 - i * 0.15) / 0.5))) if alpha > 0: - d.text((220 + int((1 - alpha) * 14), 148 + i * 34), f'✓ {item}', font=font(13), fill=(52, 211, 153, int(220 * alpha))) + d.text((220 + int((1 - alpha) * 14), 148 + i * 34), f'✓ {item}', font=font(13, 'regular'), fill=(52, 211, 153, int(220 * alpha))) elif scene_type == 'data_card': params = scene['params'] - d.text((22, 70), params['title'], font=font(16, True), fill=WHITE) + d.text((22, 70), params['title'], font=font(15, 'medium'), fill=WHITE) positions = [(22, 102), (148, 102), (22, 196), (148, 196)] for i, item in enumerate(params['items']): card_t = ease_out_cubic(min(1.0, max(0.0, (local_t - 0.25 - i * 0.14) / 0.55))) @@ -361,7 +381,7 @@ def compose_panel(scene, scene_type, local_t, scene_progress): base.alpha_composite(metric, (mx, my - int((1 - card_t) * 10))) elif scene_type == 'flow_chart': params = scene['params'] - d.text((22, 70), params['title'], font=font(16, True), fill=WHITE) + d.text((22, 70), params['title'], font=font(15, 'medium'), fill=WHITE) start_y = 112 for i, step in enumerate(params['steps']): st = ease_out_cubic(min(1.0, max(0.0, (local_t - 0.18 - i * 0.18) / 0.55))) @@ -372,8 +392,8 @@ def compose_panel(scene, scene_type, local_t, scene_progress): cx = 38 cy = y + 12 d.ellipse((cx - 12, cy - 12, cx + 12, cy + 12), fill=(accent[0], accent[1], accent[2], 220)) - d.text((cx - 4, cy - 8), str(i + 1), font=font(12, True), fill=(255, 255, 255, int(255 * st))) - d.text((64 + int((1 - st) * 18), y), step, font=font(15), fill=(TEXT[0], TEXT[1], TEXT[2], int(255 * st))) + d.text((cx - 4, cy - 8), str(i + 1), font=font(12, 'medium'), fill=(255, 255, 255, int(255 * st))) + d.text((64 + int((1 - st) * 18), y), step, font=font(14, 'regular'), fill=(TEXT[0], TEXT[1], TEXT[2], int(255 * st))) if i < len(params['steps']) - 1: for dy in range(22, 40, 5): d.ellipse((37, y + dy, 39, y + dy + 2), fill=(255, 255, 255, 45)) @@ -383,8 +403,8 @@ def compose_panel(scene, scene_type, local_t, scene_progress): center_t = ease_out_cubic(min(1.0, local_t / 0.8)) r = 34 + int(3 * math.sin(local_t * 2)) d.ellipse((cx - r, cy - r, cx + r, cy + r), fill=(52, 211, 153, int(220 * center_t))) - bb = font(14, True).getbbox(params['center']) - d.text((cx - (bb[2] - bb[0]) // 2, cy - 8), params['center'], font=font(14, True), fill=WHITE) + bb = font(14, 'medium').getbbox(params['center']) + d.text((cx - (bb[2] - bb[0]) // 2, cy - 8), params['center'], font=font(14, 'medium'), fill=WHITE) branches = params['branches'] for i, br in enumerate(branches): bt = ease_out_cubic(min(1.0, max(0.0, (local_t - 0.4 - i * 0.12) / 0.6))) @@ -396,7 +416,7 @@ def compose_panel(scene, scene_type, local_t, scene_progress): by = cy + int(math.sin(ang) * dist) accent = ACCENTS[i] d.line((cx, cy, bx, by), fill=(accent[0], accent[1], accent[2], int(130 * bt)), width=2) - ff = font(11, True) + ff = font(11, 'medium') bbox = ff.getbbox(br) tw = bbox[2] - bbox[0] th = bbox[3] - bbox[1] @@ -406,7 +426,7 @@ def compose_panel(scene, scene_type, local_t, scene_progress): else: params = scene['params'] rounded(d, (22, 60, PANEL_W - 22, 114), 22, fill=(18, 27, 44, 220), outline=(96, 165, 250, 110), width=1) - draw_wrap_center(d, params['headline'], font(22, True), PANEL_W - 80, 74, WHITE, PANEL_W) + draw_wrap_center(d, params['headline'], font(21, 'medium'), PANEL_W - 80, 74, WHITE, PANEL_W) y = 132 for i, item in enumerate(params['points']): alpha = ease_out_cubic(min(1.0, max(0.0, (local_t - 0.4 - i * 0.14) / 0.5))) @@ -414,12 +434,12 @@ def compose_panel(scene, scene_type, local_t, scene_progress): continue accent = ACCENTS[i] d.ellipse((30, y + i * 34 + 6, 38, y + i * 34 + 14), fill=(accent[0], accent[1], accent[2], int(220 * alpha))) - d.text((48 + int((1 - alpha) * 12), y + i * 34), item, font=font(14), fill=(TEXT[0], TEXT[1], TEXT[2], int(255 * alpha))) + d.text((48 + int((1 - alpha) * 12), y + i * 34), item, font=font(14, 'regular'), fill=(TEXT[0], TEXT[1], TEXT[2], int(255 * alpha))) cta_t = ease_out_cubic(min(1.0, max(0.0, (local_t - 1.2) / 0.5))) if cta_t > 0: rounded(d, (42, 286 - int((1 - cta_t) * 8), PANEL_W - 42, 316 - int((1 - cta_t) * 8)), 16, fill=(52, 211, 153, int(220 * cta_t))) - draw_center(d, params['cta'], font(13, True), 293 - int((1 - cta_t) * 8), WHITE, PANEL_W) + draw_center(d, params['cta'], font(13, 'medium'), 293 - int((1 - cta_t) * 8), WHITE, PANEL_W) chips = [('AI安装', BLUE), ('远程交付', PURPLE), ('可变现', GREEN)] for i, (txt, accent) in enumerate(chips): diff --git a/运营中枢/工作台/gitea_push_log.md b/运营中枢/工作台/gitea_push_log.md index c20a010f..c60c5f87 100644 --- a/运营中枢/工作台/gitea_push_log.md +++ b/运营中枢/工作台/gitea_push_log.md @@ -285,3 +285,4 @@ | 2026-03-11 09:35:20 | 🔄 卡若AI 同步 2026-03-11 09:35 | 更新:卡木、火炬、总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 | | 2026-03-11 09:56:46 | 🔄 卡若AI 同步 2026-03-11 09:56 | 更新:卡木、运营中枢工作台 | 排除 >20MB: 11 个 | | 2026-03-11 13:54:29 | 🔄 卡若AI 同步 2026-03-11 13:54 | 更新:卡木、运营中枢工作台 | 排除 >20MB: 11 个 | +| 2026-03-11 14:38:13 | 🔄 卡若AI 同步 2026-03-11 14:38 | 更新:卡木、运营中枢工作台 | 排除 >20MB: 11 个 | diff --git a/运营中枢/工作台/代码管理.md b/运营中枢/工作台/代码管理.md index e6ebf885..bba99653 100644 --- a/运营中枢/工作台/代码管理.md +++ b/运营中枢/工作台/代码管理.md @@ -288,3 +288,4 @@ | 2026-03-11 09:35:20 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-11 09:35 | 更新:卡木、火炬、总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) | | 2026-03-11 09:56:46 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-11 09:56 | 更新:卡木、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) | | 2026-03-11 13:54:29 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-11 13:54 | 更新:卡木、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) | +| 2026-03-11 14:38:13 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-11 14:38 | 更新:卡木、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |