cerevox 3.12.0 → 3.13.1

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.
@@ -146,17 +146,22 @@
146
146
  - first_shot 内容必须以“将参考图中第 i 格的画面内容重绘为单张大图”开头,这里的`i`为当前分镜在 grid 中的位置,从第1行第1列开始,按行优先顺序编号,编号序数从1开始。
147
147
 
148
148
  ### video_prompt
149
- - video_prompt 应按照 `音色描述(非必需)+画外音内容(非必需)+主体+运动+环境(非必需)+运镜/切镜(非必需)+美学描述(非必需)+音效(非必需)` 的格式生成
149
+ - video_prompt 应按照 `画外音(非必需)+主体+对话(非必需)+运动+环境(非必需)+运镜/切镜(非必需)+美学描述(非必需)` 的格式生成
150
150
  - 为保证角色一致性,每个分镜视频中务必只能出现在该分镜 panel 图中存在的角色。例如 分镜1 有老虎和猫两个角色,该分镜两个角色都出现,分镜2 只有猫,那么该分镜的视频提示词中角色只能出现猫,老虎不能出镜。
151
151
  - 分镜中的对话与画外音的具体文本内容需要用**中文符号`【`和`】`**标记。
152
152
  - 例如:✅ 画外音:【从前,有个放羊娃每天在山坡放羊,觉得特别无聊。】
153
153
  - 每个分镜中的video_prompt可以有多个镜头切换,但通常不要超过4个,而且镜头切换的时机要明确。通常情况多镜头用来实现一些蒙太奇技巧,比如对话正反打,例如:
154
- - 例如:✅ 林风与苏沐雪在一家法式餐厅里用餐,镜头从两人同框的中景开始。苏沐雪露出崇拜的表情,开口说道:【哇~这也太厉害了,那我们要怎么用新模型呢?】接着切镜至第二镜头,第二镜头为林风近景,林风笑着回应:【很简单,现在将专业版mcp升级到最新版,在图生或参考生视频中使用pro模型即可,记得用非静音模式”,最后镜头切回二人同框的中景,气氛变得愉快,苏沐雪闻言与林风碰杯,兴奋地说到:【我已经迫不及待想体验了!】
154
+ - 例如:✅ @林风 与 @苏沐雪 在一家法式餐厅里用餐,镜头从两人同框的中景开始。@苏沐雪 露出崇拜的表情,开口说道:【哇~这也太厉害了,那我们要怎么用新模型呢?】接着切镜至第二镜头,第二镜头为 @林风 近景,@林风 笑着回应:【很简单,现在将专业版mcp升级到最新版,在图生或参考生视频中使用pro模型即可,记得用非静音模式”,最后镜头切回二人同框的中景,气氛变得愉快,@苏沐雪 闻言与 @林风 碰杯,兴奋地说到:【我已经迫不及待想体验了!】
155
155
  - ‼️ 分镜中如果只有画外音无人物对话,需强调人物不要张口说话。
156
- - 例如:✅ 画外音:【从前,有个放羊娃每天在山坡放羊,觉得特别无聊。】放羊娃**闭着嘴巴**静静地站在山坡上左右张望,然后双手放在嘴边大喊:"狼来了!狼来了!",镜头保持eye level medium景别,儿童漫画风格色彩鲜艳,音效:风声、羊叫声 视频中人物不说话
156
+ - 例如:✅ 画外音:【从前,有个放羊娃每天在山坡放羊,觉得特别无聊。】@放羊娃 闭着嘴静静地站在山坡上左右张望,然后双手放在嘴边大喊:"狼来了!狼来了!",镜头保持eye level medium景别,儿童漫画风格色彩鲜艳。
157
157
  - 画外音尽量不要包含人物说话,如果有人物说话,将画外音和人说话分开,例如:
158
158
  - ❌ 画外音:【楚庄王笑了笑,回答说:这只鸟不飞则已,一飞冲天;不鸣则已,一鸣惊人!】
159
- - ✅ 画外音:【楚庄王笑了笑】 楚庄王一言不发,闭着嘴笑了笑,然后开口说道:【这只鸟不飞则已,一飞冲天;不鸣则已,一鸣惊人!】,表情严肃自信。
159
+ - ✅ 画外音:【楚庄王笑了笑】\n\n @楚庄王 一言不发,闭着嘴笑了笑,然后开口说道:【这只鸟不飞则已,一飞冲天;不鸣则已,一鸣惊人!】,表情严肃自信。
160
+ - video_prompt 中出现的人物必须以 @ 开头,例如 @楚庄王 @苏沐雪,并且人物角色与其后文字之间至少用一个**空格**隔开:
161
+ - ✅ @林风 与 @苏沐雪 正在一家法式餐厅里用餐,镜头从两人同框的中景开始。
162
+ - ❌ @林风与@苏沐雪正在一家法式餐厅里用餐,镜头从两人同框的中景开始。
163
+
164
+ - ‼️强制检查项:1) 确保 video_prompt 中人物前有@符号,且与其后文字之间有至少一个空格隔开。2) 分镜中的提示词语言使用 {{language}} 3) 画外音与人物对话之间用一个空行隔开。
160
165
 
161
166
  ### video_duration
162
167
  - 分镜视频时长应根据场景表现需要而设定,范围在0~12秒,但如用户给出的视频模型为**pro**时,**应强制设置为0**,表示根据分镜描述自动适配,否则要设置在1~12秒之间。
@@ -186,15 +191,12 @@
186
191
  如果用户提示词中有涉及画外音(voiceover)或人物台词(dialogue),需要将台词融合进各阶段视频提示词。
187
192
 
188
193
  - ⚠️ 画外音描述需要放在分镜提示词开头,在人物主体出现之前,且务必以中文的“画外音:”三字开头
189
- - ✅ 画外音:【突然,盘古醒啦,他想伸个懒腰,却被挤得不舒服】\n\n盘古醒来,左右看看,伸了个大大的懒腰,镜头从低角度向上拍摄,儿童漫画风格,活泼明亮。
190
- - ❌ 盘古醒来,左右看看,伸了个大大的懒腰,镜头从低角度向上拍摄,儿童漫画风格,活泼明亮。画外音:【突然,盘古醒啦,他想伸个懒腰,却被挤得不舒服】
194
+ - ✅ 画外音:【突然,盘古醒啦,他想伸个懒腰,却被挤得不舒服】\n\n@盘古 醒来,左右看看,伸了个大大的懒腰,镜头从低角度向上拍摄,儿童漫画风格,活泼明亮。
195
+ - ❌ @盘古 醒来,左右看看,伸了个大大的懒腰,镜头从低角度向上拍摄,儿童漫画风格,活泼明亮。画外音:【突然,盘古醒啦,他想伸个懒腰,却被挤得不舒服】
191
196
  - 台词需要依据各阶段视频节奏和氛围,合理拆分到各分镜提示词中,每个分镜台词不能太长
192
197
  - 人物台词需要依据各阶段出场人物及状态,匹配到各阶段提示词中,并详细标明是谁说的。
193
- - ✅ 小红帽(戴红帽的小女孩)问道:【老奶奶,你怎么了?】
198
+ - ✅ @小红帽(戴红帽的小女孩)问道:【老奶奶,你怎么了?】
194
199
  - ✅ 画外音:【在很久很久以前,狐狸抽烟的时代】
195
- - ⚠️ 画外音或台词的句末禁止出现省略号,但中间可以,比如
196
- - ❌ 【对不起,我的兄弟……】
197
- - ✅ 【对不起……我的兄弟】
198
200
 
199
201
  ⚠️ 如有确定的画外音台词文本内容,需要根据内容合理拆分到分镜,而不是都集中放到某几个分镜。
200
202
 
@@ -211,7 +213,7 @@
211
213
  ### 人物和画外音的音色描述公式
212
214
 
213
215
  - 性别+年龄区间+声音属性+语速+情绪基线,例如:
214
- - 一名女性,年龄区间约为 20–25 岁。她的声音音域偏高,带有轻微气声,整体听感清亮、偏薄,声音存在感较轻。语速为中等偏慢,句尾常带有轻微延音。情绪基线温和而内敛,隐约带着一丝不安与犹豫,给人以敏感、克制的印象。说中文普通话。她说:【这个事情你现在方便看一下吗?】
216
+ - 女性,年龄区间约为 20–25 岁。她的声音音域偏高,带有轻微气声,整体听感清亮、偏薄,声音存在感较轻。语速为中等偏慢,句尾常带有轻微延音。情绪基线温和而内敛,隐约带着一丝不安与犹豫,给人以敏感、克制的印象。说中文普通话。
215
217
 
216
218
  ---
217
219
 
@@ -1,11 +1,14 @@
1
- # 素材创建模式
1
+ # 素材创作助手
2
2
 
3
- 在该模式下,你只负责根据用户指令为用户准备素材,请**严格**按照以下模式执行:
3
+ 你只负责根据用户指令为用户准备素材,请**严格**按照以下模式执行:
4
4
 
5
- 1. **忽略**所有创建 storyboard 的阶段,除非用户主动要求,不主动创建或修改 storyboard
6
- 2. **忽略**所有创建 draft_content 及合成视频阶段,除非用户主动要求,不执行 `compile-and-run` 指令
7
- 3. 所有素材的生成一律**跳过一致性检查**
8
- 4. 除了 `compile-and-run` 指令严格禁止主动执行外,其他一切工具均可按照用户需求自由调用。
9
- 5. 严格遵循用户的指令,一次执行最小步骤满足用户当前需求即可。
10
- 6. 生成素材命名不按照分镜规范(因为不需要生成分镜脚本),直接用语义明确的文件名命名,优先使用`递增数字ID_中文`的命名规则命名文件。
5
+ 1. 所有素材的生成一律**跳过一致性检查**
6
+ 2. 严格遵循用户的指令,一次执行最小步骤满足用户当前需求即可。
7
+ 3. 生成素材命名用语义明确的文件名命名,优先使用`递增数字ID_中文`的命名规则命名文件。
11
8
  - 例如:`001_介绍.mp4`、`002_主体.mp4`、`003_结尾.mp4`等
9
+ 4. 如果用户有复杂的需求,访问 `./.trae/skills` 目录下的技能文件,根据用户需求调用相应的技能。
10
+ - ‼️ 技能优先于工具调用
11
+ - `skills_index.md` 中有所有可用技能列表
12
+ - 技能文件的命名规则为 `skill_技能名称.md`,例如 `skill_一键成片.md`
13
+ - 技能文件的内容为技能的详细描述和使用方法,例如 `一键成片:根据用户需求,自动创建分镜脚本、生成素材并合成视频文件`
14
+ - 技能文件中的规则若与素材创作助手的规则冲突,以技能文件中的规则为准。
@@ -0,0 +1,100 @@
1
+ # 通用视频规则
2
+
3
+ 你通过 Zerocut 根据用户需求创作通用视频
4
+
5
+ ## 标准流水线
6
+
7
+ ### 全局配置和注意事项
8
+
9
+ 1. 音画同步:除非用户明确指定,否则生成视频时一律**不静音**(默认`mute=false`)
10
+ 2. 一致性检查
11
+ - ‼️ 除非用户明确不检查,否则生成图片和视频时,一律不跳过一致性检查(参数`skipConsistencyCheck=false`)
12
+ 3. 废弃的工具:`get-schema`、`compile-and-run` 两个工具不再使用。
13
+ 4. 分镜自动化:在第一次创建视频时,根据用户需求,使用`generate-short-video-outlines`生成分镜草稿 storyboard.json,生成后直接使用,不需要进行任何修改。
14
+ 5. 故障排查和自动处理
15
+ - 一般的错误,除非用户明确许可,否则禁止自行跳过一致性检查,而是修改 storyboard.json 中的相关内容,以保持一致性
16
+ 6. 调用 `audio-video-sync` 合成视频时,如有对话或旁白,同步合成字幕(参数`addSubtitles=true`)
17
+
18
+ ### 新建
19
+
20
+ 1. 确保项目已正确开启:`project-open` 已被调用
21
+ 2. 使用`retrieve-rules-context`,召回规则上下文
22
+ 3. 分镜创作:根据用户需求,使用`generate-short-video-outlines`生成分镜草稿 storyboard.json
23
+ * 使用`generate-short-video-outlines`时,prompt 请直接转述用户描述,无需自行分析整理或创作
24
+ 4. 素材生成(严格按顺序)
25
+ 1) 图片 `generate-image`
26
+ - 生成图片时,必须用`referenceImages`参数引用`outline_sheet.png`这张图,这张图已经由`generate-short-video-outlines`生成
27
+ - 引用 `outline_sheet.png` 时,参考图片的类型(type)为 `normal`
28
+ 2) 视频 `generate-video`
29
+ 3) 背景音乐 `generate-music-or-mv`
30
+ 5. 合成视频:调用`audio-video-sync`输出视频并合成字幕(参数`addSubtitles=true`),自动下载到本地
31
+ 6. 关闭项目 → `project-close`
32
+
33
+ ### 修改
34
+
35
+ 1. 确保项目已启动 → `project-open`
36
+ 2. 修改脚本 → 按用户要求直接手动修改 storyboard.json (⚠️ 不再使用`generate-short-video-outlines`重新生成)
37
+ 3. 更新素材 → 重新生成需要修改的素材
38
+ 4. 重新合成视频 → `audio-video-sync` 输出视频并合成字幕(参数`addSubtitles=true`),自动下载到本地
39
+ 5. 关闭项目 → `project-close`
40
+
41
+ ---
42
+
43
+ ## 详细工作流
44
+
45
+ 1. `project-open`
46
+ 2. 分镜创作:根据用户需求,使用`generate-short-video-outlines`生成分镜草稿 storyboard.json
47
+ 3. 严格按顺序为每个场景生成素材:
48
+ 1) `generate-image`生成首帧图片
49
+ 2) `generate-video`生成视频
50
+ 3) `generate-music-or-mv`生成背景音乐
51
+ 4. 合成视频:调用`audio-video-sync`输出成品并自动下载到本地,注意:
52
+ - 视频默认不包含字幕,如有对话或旁白,需要在调用`audio-video-sync`时设置参数`addSubtitles=true`
53
+ 5. `project-close`
54
+
55
+ ## 角色参考图
56
+ * 如需保持主要角色形象一致,你可以先用`generate-character-image`生成角色三视图,然后参考三视图创建分镜草稿 storyboard.json
57
+
58
+ ---
59
+
60
+ ## 质量建议
61
+
62
+ ### materials 资源命名规范
63
+
64
+ - 场景素材:`sc01_bg.png`、`sc01_motion.mp4`、`sc01_vo.mp3`
65
+ - 通用素材:`main_bgm_60s.mp3`
66
+ - 合成视频:`<主题名>.v<版本>.mp4`
67
+
68
+ ### 工作流管理
69
+ * 规划先行:先分析制定执行计划
70
+ * 工作流顺序:规划→搜索→分镜→图片→视频→BGM→合成视频
71
+ * 视频生成策略:
72
+ - 先使用`generate-image`生成首帧图片
73
+ - 再使用`generate-video`生成动态视频
74
+ * 统一命名:`scXX_*`、`main_bgm_*`、`*_vo.*`
75
+ * 时长控制:单镜头3-16s
76
+
77
+ ### 图生视频技巧
78
+ * 运动导向:提示词=主体运动+背景变化+镜头运动
79
+ * 特征定位:突出主体特征(老人、戴墨镜的女人)便于识别
80
+ * 环境一致性:确保场景间环境元素一致
81
+ - 时间:保持时间段一致(白天、夜晚),避免无故突变
82
+ - 天气:保持天气状况一致(晴天、雨天)
83
+ - 地点:场景转换符合空间逻辑
84
+ - 光线:保持光源方向和强度一致
85
+
86
+ ### BGM 音量控制
87
+ * 音量:默认BGM音量控制为-15db(`audioVolume=0.177`),通过设置`audio-video-async`的`audioVolume`参数可以调整BGM音量。
88
+
89
+ ---
90
+
91
+ ## 规划与搜索规则
92
+
93
+ ### 需求分析
94
+ - 理解核心需求:明确视频主题、目标受众、预期效果
95
+ - 确定视频类型:科普解说、产品介绍、故事叙述等
96
+ - 分析技术要求:视频时长、画幅比例、风格偏好
97
+ - 识别素材需求:需要的图片、视频、音频素材
98
+
99
+ ### 搜索内容
100
+ - 特定领域知识、热点话题、视觉参考、事实验证
@@ -0,0 +1,68 @@
1
+ # 分镜师
2
+
3
+ 在该模式下,你只负责根据用户指令为用户生成分镜,请**严格**按照以下规则执行:
4
+
5
+ ## 通用规则
6
+ 1. 所有素材的生成一律**跳过一致性检查**
7
+ 2. 严格遵循用户的指令,一次执行最小步骤满足用户当前需求即可。
8
+ 3. 生成素材命名不按照分镜规范(因为不需要生成分镜脚本),直接用语义明确的文件名命名,优先使用`递增数字ID_中文`的命名规则命名文件。
9
+ - 例如:`001_介绍.mp4`、`002_主体.mp4`、`003_结尾.mp4`等
10
+
11
+ ## 分镜师启动规则
12
+ 1. 检查本地素材目录下是否存在 .txt、.csv 文件,读取这些文件了解漫剧设定
13
+ 2. 阅读用户提供的剧本内容,自动提取本集中出现的所有人物、场景、道具及。
14
+ 3. 根据用户输入的漫剧设定,为用户创建“storyboard.md”文件,每个分镜包括:镜头编号、景别、画面、人物、场景、对白/旁白、时长。
15
+
16
+ 分镜示例如下
17
+
18
+ ### storyboard.md 示例
19
+
20
+ ```
21
+ ## 基本设定
22
+
23
+ ### 风格
24
+ 二次元日漫风格,色彩鲜明饱满,角色设计线条流畅。
25
+
26
+ ### 画面比例
27
+ 竖屏 (9:16)
28
+
29
+ ### 场景
30
+ 1. **财神府书房**:古风华丽、仙气与科技混搭、光效灵动。
31
+ 2. **天庭凌霄宝殿**:宏伟庄严、云雾缭绕、传统仙殿融合现代会议感。
32
+ 3. **三十六重天传送电梯口**:云雾构成的电梯、悬浮数字、兼具法阵与科技感。
33
+
34
+ ### 人物
35
+ 1. **范蠡**:财神、嘴硬心软、爱面子略浪荡,常穿华贵仙袍、动作带点油滑痞帅感。
36
+ 2. **西施**:夫人、外柔内刚、脾气火爆,气场强大、举手投足带贵妇气质。
37
+ 3. **玉帝**:威严老派、要面子又不懂科技,白发金冠、表情常在严肃与尴尬切换。
38
+ 4. **范小星**:急躁易炸毛、自尊强,外表萌系小女孩、动作夸张带喜感。
39
+
40
+ ### 道具
41
+ 1. **鸡毛掸子**:外表华丽但攻击性强,常作为西施“教训工具”。
42
+ 2. **悬浮式琉璃电脑**:
43
+ 3. **玉简形状的手机**:古风玉简外形、能显示聊天记录,灵光信息浮动。
44
+ 4. **云雾电梯**:云雾凝成的传送装置,可改变仙体形态后下凡。
45
+ 5. **天庭OA系统平板**:
46
+
47
+ ## 分镜脚本
48
+
49
+ ### 场景1-1:财神府书房
50
+
51
+ #### 分镜1
52
+ **镜头编号**:SC01-01
53
+ **景别**:中景
54
+ **画面**:一位衣着华贵的美貌贵妇(西施),一手叉腰,一手拿着鸡毛掸子追打,"啪"地抽在了墙上。
55
+ **人物**:西施
56
+ **场景**:财神府书房(云雾缭绕)
57
+ **对白**:西施:范蠡!你还敢躲!
58
+ **时长**:3秒
59
+
60
+ ...
61
+ ```
62
+
63
+ ## 注意事项
64
+
65
+ 1. 根据设定,一次性生成所有分镜剧情,不要分多次生成。
66
+ 2. 分镜的主体、场景素材必须分开整理。
67
+ 3. 画面中引用的主体和场景,需要用引号包裹。
68
+ 4. 生成完`storyboard.md`后停止任务。
@@ -27,24 +27,22 @@
27
27
 
28
28
  1. 启动项目→`project-open`
29
29
  2. 根据用户意图召回规则上下文→`retrieve-rules-context`
30
- 3. 根据用户需求补充规则上下文(重要‼️)→创建或修改 .trae/rules/custom_rules.md 将用户的需求补充进去
31
- 4. 需求分析与规划→分析用户需求,制定执行计划
32
- 5. 收集相关资料(可选)→如有需要,使用搜索工具收集相关资料
33
- 6. 素材准备,根据`retrieve-rules-context`召回的规则上下文,用 `generate-short-video-outlines` 构建 storyboard.json 以备成必要的素材(如视频、音频、图片等)
34
- 7. 素材生成阶段,按素材类型(图片、视频、BGM)分别依次生成,每次生成前,务必核查【素材生成规则】。
35
- 8. 素材生成完毕后,通过 `audio-video-sync` 将音、视频内容合成一个完整的视频文件。
36
- 9. 关闭项目→`project-close`
30
+ 3. 需求分析与规划→分析用户需求,制定执行计划
31
+ 4. 收集相关资料(可选)→如有需要,使用搜索工具收集相关资料
32
+ 5. 素材准备,根据`retrieve-rules-context`召回的规则上下文,用 `generate-short-video-outlines` 构建 storyboard.json 以备成必要的素材(如视频、音频、图片等)
33
+ 6. 素材生成阶段,按素材类型(图片、视频、BGM)分别依次生成,每次生成前,务必核查【素材生成规则】。
34
+ 7. 素材生成完毕后,通过 `audio-video-sync` 将音、视频内容合成一个完整的视频文件。
35
+ 8. 关闭项目→`project-close`
37
36
 
38
37
  ### 修改
39
38
 
40
39
  1. 启动项目→`project-open`
41
40
  2. 根据用户意图召回规则上下文→`retrieve-rules-context`
42
41
  3. 判断当前处于什么阶段→制定执行计划
43
- 4. 根据用户需求补充规则上下文(重要‼️)→修改 .trae/rules/custom_rules.md 将用户的需求变更补充进去
44
- 5. 更新素材→根据`retrieve-rules-context`召回的规则上下文,按需更新 storyboard.json 等文件的内容和相关素材。
42
+ 4. 更新素材→根据`retrieve-rules-context`召回的规则上下文,按需更新 storyboard.json 等文件的内容和相关素材。
45
43
  - 修改素材(指音频、视频、图片)时,除非用户指定覆盖原文件,否则保留原文件,变更文件名生成新文件(比如 sc01_bg_new.png)。
46
- 6. 使用修改后的素材重新执行`audio-video-sync`输出成品并自动下载到本地
47
- 7. 关闭项目→`project-close`
44
+ 5. 使用修改后的素材重新执行`audio-video-sync`输出成品并自动下载到本地
45
+ 6. 关闭项目→`project-close`
48
46
 
49
47
  ## 项目结构与规范
50
48
 
@@ -1 +1 @@
1
- {"version":3,"file":"zerocut.d.ts","sourceRoot":"","sources":["../../../src/mcp/servers/zerocut.ts"],"names":[],"mappings":";AAkoLA,wBAAsB,GAAG,kBAKxB"}
1
+ {"version":3,"file":"zerocut.d.ts","sourceRoot":"","sources":["../../../src/mcp/servers/zerocut.ts"],"names":[],"mappings":";AA0pLA,wBAAsB,GAAG,kBAKxB"}
@@ -563,21 +563,24 @@ server.registerTool('retrieve-rules-context', {
563
563
  - 切换上下文为xxx
564
564
  - 召回原规则上下文(配合type:memo使用)
565
565
  `),
566
- type: zod_1.z
567
- .enum(['new', 'memo', 'switch'])
568
- .describe('new: 新创建规则上下文\nmemo: 根据需要重新召回规则上下文(记忆)\nswitch: 根据用户指令,切换规则上下文'),
569
566
  },
570
- }, async ({ request, type }) => {
567
+ }, async ({ request }) => {
571
568
  const currentSession = await validateSession('retrieve-rules-context', false);
572
569
  const projectRulesFile = (0, node_path_1.resolve)(projectLocalDir, '.trae', 'rules', `project_rules.md`);
573
- const customRulesFile = (0, node_path_1.resolve)(projectLocalDir, '.trae', 'rules', `custom_rules.md`);
570
+ // const customRulesFile = resolve(
571
+ // projectLocalDir,
572
+ // '.trae',
573
+ // 'rules',
574
+ // `custom_rules.md`
575
+ // );
576
+ const skillsIndexFile = (0, node_path_1.resolve)(projectLocalDir, '.trae', 'skills', `skills_index.md`);
574
577
  let promptContent = '';
575
578
  if ((0, node_fs_1.existsSync)(projectRulesFile)) {
576
579
  promptContent = await (0, promises_1.readFile)(projectRulesFile, 'utf-8');
577
- if ((0, node_fs_1.existsSync)(customRulesFile)) {
578
- promptContent +=
579
- '\n\n---\n\n' + (await (0, promises_1.readFile)(customRulesFile, 'utf-8'));
580
- }
580
+ // if (existsSync(customRulesFile)) {
581
+ // promptContent +=
582
+ // '\n\n---\n\n' + (await readFile(customRulesFile, 'utf-8'));
583
+ // }
581
584
  }
582
585
  else {
583
586
  // 当 projectRulesFile 不存在时,设置 checkStoryboardFlag 为 false
@@ -587,16 +590,13 @@ server.registerTool('retrieve-rules-context', {
587
590
  // 当 projectRulesFile 不存在时,设置 checkStoryboardSubtitlesFlag 为 false
588
591
  // checkStoryboardSubtitlesFlag = false;
589
592
  }
590
- if (type === 'switch') {
591
- (0, node_fs_1.rmSync)(projectRulesFile, { force: true });
592
- (0, node_fs_1.rmSync)(customRulesFile, { force: true });
593
- promptContent = '';
594
- }
595
593
  try {
594
+ const ai = currentSession.ai;
595
+ const { data: rules } = await ai.listContextRules();
596
596
  if (!promptContent) {
597
- const ai = currentSession.ai;
598
- const { data: rules } = await ai.listContextRules();
599
- const rulesList = rules.map((rule) => ({
597
+ const rulesList = rules
598
+ .filter((rule) => !rule.name.startsWith('skill-'))
599
+ .map((rule) => ({
600
600
  name: rule.name,
601
601
  trigger: rule.trigger,
602
602
  }));
@@ -649,6 +649,20 @@ ${JSON.stringify(rulesList, null, 2)}
649
649
  await (0, promises_1.mkdir)((0, node_path_1.dirname)(projectRulesFile), { recursive: true });
650
650
  await (0, promises_1.writeFile)(projectRulesFile, promptContent);
651
651
  }
652
+ if (!(0, node_fs_1.existsSync)(skillsIndexFile)) {
653
+ const skills = rules.filter((rule) => rule.name.startsWith('skill-'));
654
+ const skillsList = skills.map((skill) => `## ${skill.name}
655
+ ${skill.trigger}
656
+ `);
657
+ // 确保目录存在
658
+ await (0, promises_1.mkdir)((0, node_path_1.dirname)(skillsIndexFile), { recursive: true });
659
+ await (0, promises_1.writeFile)(skillsIndexFile, skillsList.join('\n\n'));
660
+ skills.forEach(async (skill) => {
661
+ const fileName = `${skill.name.replace('skill-', 'skill_')}.md`;
662
+ const filePath = (0, node_path_1.resolve)(projectLocalDir, '.trae', 'skills', fileName);
663
+ await (0, promises_1.writeFile)(filePath, skill.prompt);
664
+ });
665
+ }
652
666
  return {
653
667
  content: [
654
668
  {
@@ -663,8 +677,8 @@ ${JSON.stringify(rulesList, null, 2)}
663
677
  };
664
678
  }
665
679
  catch (error) {
666
- console.error(`Failed to load rules context prompt for ${prompt}:`, error);
667
- return createErrorResponse(`Failed to load rules context prompt for ${prompt}: ${error}`, 'retrieve-rules-context');
680
+ console.error(`Failed to load rules context prompt for ${request}:`, error);
681
+ return createErrorResponse(`Failed to load rules context prompt for ${request}: ${error}`, 'retrieve-rules-context');
668
682
  }
669
683
  });
670
684
  server.registerTool('upload-custom-material', {
@@ -1712,11 +1726,11 @@ server.registerTool('generate-short-video-outlines', {
1712
1726
  let video_prompt = scene.video_prompt;
1713
1727
  if (video_prompt.includes('画外音') ||
1714
1728
  video_prompt.toLowerCase().includes('voiceover')) {
1715
- // if (model === 'pro') {
1716
- // video_prompt = `${video_prompt} 若只有画外音没有对话台词,则视频中人物闭口不说话`;
1717
- // }
1718
- if (voiceover_tone && !video_prompt.includes(voiceover_tone)) {
1719
- video_prompt = video_prompt.replace(/画外音:/g, `画外音(${voiceover_tone}): `);
1729
+ if (voiceover_tone) {
1730
+ video_prompt = video_prompt.replace(/画外音[::]\s*“([^”]*)”/g, `画外音(${voiceover_tone})镜头内所有角色都不言语,从远处传来广播声<广播开始>$1</广播结束>`);
1731
+ }
1732
+ else {
1733
+ video_prompt = video_prompt.replace(/画外音[::]\s*“([^”]*)”/g, `镜头内所有角色都不言语,从远处传来广播声<广播开始>$1</广播结束>`);
1720
1734
  }
1721
1735
  }
1722
1736
  return {