用途
该技能用于自动化 Adobe After Effects,方式是生成 ExtendScript(.jsx)脚本并通过 osascript 执行。当用户要求创建、修改或查询 After Effects 项目中的任何内容(图层、关键帧、表达式、合成、效果、素材、渲染等)时使用。技能通过查询脚本读取项目状态,使用规则文件提供领域知识,并将所有修改操作包裹在撤销组中。
首次设置
- 运行 scripts/runner.sh 并附带任意查询脚本以检测 AE 版本。
- 如果安装了多个 AE 版本,用户必须选择一个,runner.sh 会提示。
- 确保 AE 首选项 > 脚本与表达式 > “允许脚本写入文件和访问网络”已启用。
工作流程
对每个用户请求:
第 1 步:收集上下文(自动运行,无需确认)
运行活动状态查询:
bash scripts/runner.sh scripts/active-state.jsx
然后读取 /tmp/ae-assistant-result.json 获取活动合成、选中图层、CTI。
如果是首次交互或项目上下文未知,还需运行:
bash scripts/runner.sh scripts/project-overview.jsx
默认返回摘要:带计数的文件夹树、所有合成列表、按文件类型分组的素材,而非每个单独文件。
深入特定文件夹:
bash scripts/runner.sh scripts/project-overview.jsx '{"mode": "folder", "folderName": "Images"}'
仅在确实需要列出每个项目时才使用 full 模式:
bash scripts/runner.sh scripts/project-overview.jsx '{"mode": "full"}'
第 2 步:按需深入(自动运行)
如果任务针对特定合成:
bash scripts/runner.sh scripts/comp-detail.jsx '{"compName": "Comp Name"}'
如果任务针对特定图层:
bash scripts/runner.sh scripts/layer-detail.jsx '{"layerNames": ["Layer 1", "Layer 2"]}'
省略 compName 则使用活动合成。省略 layerNames 则使用选中图层。
第 3 步:加载领域知识
从 rules/ 读取相关规则文件。始终读取 rules/extendscript-fundamentals.md,其中包含适用于每个生成脚本的 ES3 约束。
| 任务涉及 | 加载规则文件 |
|---|---|
| 图层(创建、移动、父级、复制) | rules/layer-manipulation.md |
| 关键帧、动画、缓动 | rules/keyframes-animation.md |
| 表达式 | rules/expressions.md |
| 合成(创建、预合成、嵌套) | rules/composition-management.md |
| 效果与参数 | rules/effects.md |
| 导入、素材、资产 | rules/assets-footage.md |
| 渲染队列、导出 | rules/rendering.md |
| 批量操作 | rules/batch-operations.md |
| 版本特定功能 | references/ae-api-versions.md |
第 4 步:生成动作脚本
关键:先解析技能的真实路径
在编写或执行任何动作脚本之前,解析技能的真实(非符号链接)路径。ExtendScript 的 #include 无法跟随符号链接,因此必须使用真实文件系统路径。
每个会话开始时运行一次:
SKILL_SCRIPTS="$(readlink -f ~/.claude/skills/after-effects-assistant/scripts 2>/dev/null || readlink ~/.claude/skills/after-effects-assistant/scripts)"
echo "$SKILL_SCRIPTS"
在本次会话的所有后续 Write 和 Bash 命令中使用解析后的路径($SKILL_SCRIPTS)。
原因:
- ~/.claude/skills/ 通常是符号链接,ExtendScript 的 #include 无法通过符号链接。
- 写入真实 scripts/ 目录可让 #include "lib/json2.jsx" 正确解析。
- 解析后的路径因机器而异,切勿硬编码。
每个生成的脚本必须遵循以下模板:
#include "lib/json2.jsx"
#include "lib/utils.jsx"
(function() {
app.beginUndoGroup("AE Assistant: <action description>");
try {
var args = readArgs();
var comp = app.project.activeItem;
if (!comp || !(comp instanceof CompItem)) {
writeResult({ error: "No active composition" });
return;
}
// ... action code ...
writeResult({ success: true, message: "<what was done>" });
} catch (e) {
try { writeResult({ error: e.toString(), line: e.line, fileName: e.fileName }); }
catch(e2) { writeError(e.toString(), "line:" + e.line); }
} finally {
app.endUndoGroup();
}
})();
使用 Write 工具编写脚本,然后用简短的 bash 命令执行:
- 使用 Write 工具将脚本写入 $SKILL_SCRIPTS/ae-action.jsx(解析后的真实路径)。
- 用 bash 执行:
bash "$SKILL_SCRIPTS/runner.sh" "$SKILL_SCRIPTS/ae-action.jsx"
重要:不要使用 cat > file << 'SCRIPT' heredoc,它们会把整个脚本放进 bash 命令,使权限提示混乱。始终使用 Write 工具编写脚本内容,然后用简短 bash 命令运行。
第 5 步:执行或确认
自动运行(无需确认):
- 所有只读查询(active-state、project-overview、comp-detail、layer-detail)
- 非破坏性新增:添加关键帧、添加效果、创建图层、创建合成
运行前确认(展示脚本并询问用户):
- 删除图层或合成
- 移除关键帧
- 替换素材
- 清除表达式
- 渲染队列操作
- 任何用户可能未预期的操作
第 6 步:执行并读取结果
# 执行动作脚本(已在第 4 步写入 $SKILL_SCRIPTS/ae-action.jsx)
bash "$SKILL_SCRIPTS/runner.sh" "$SKILL_SCRIPTS/ae-action.jsx" '{"arg1": "value1"}'
读取 /tmp/ae-assistant-result.json 获取结果。
调试失败
如果脚本失败,按顺序检查:
- ~/.ae-assistant-log — runner.sh 在此记录每次执行、参数、结果和错误。
- /tmp/ae-assistant-error.txt — JXA 级错误(AE 无响应、DoScriptFile 失败)。
- ~/.ae-assistant-extendscript.log — 来自 utils.jsx 中 appendLog() 的 ExtendScript 级日志。
- AE 首选项 — 确保“允许脚本写入文件和访问网络”已启用。
发生错误时,读取 ~/.ae-assistant-log 了解情况,修复脚本并重试。
必须遵守
- 始终将修改包裹在 app.beginUndoGroup() / app.endUndoGroup() 中。
- 始终使用 matchNames 访问属性,而非显示名称(显示名称已本地化)。
- 始终对图层和项目项使用从 1 开始的索引。
- 始终将动作脚本写入 $SKILL_SCRIPTS/ae-action.jsx(解析后的真实路径,而非 /tmp/)。
- 始终使用相对 #include "lib/json2.jsx" 和 #include "lib/utils.jsx"(而非绝对路径)。
- 始终包裹在 IIFE 中以避免全局作用域污染。
- 始终使用 var,绝不使用 let 或 const(ES3)。
- 始终通过 writeResult() 将结果写入 /tmp/ae-assistant-result.json。
- 始终在访问 comp 属性前检查 comp instanceof CompItem。
禁止事项
- 绝不使用 ES5+ 语法:let、const、箭头函数、模板字面量、解构。
- 绝不使用 Array.map、Array.filter、Array.reduce、Array.forEach(ES3 中没有)。
- 绝不使用 JSON.parse 或 JSON.stringify 而不包含 json2.jsx。
- 绝不将动作脚本写入 /tmp/ — ExtendScript 的 #include 无法从那里解析路径。
- 绝不在 #include 中使用绝对路径 — 它们会因符号链接而失效。
- 绝不硬编码图层索引 — 使用名称、选择或迭代。
- 绝不在未经用户确认的情况下运行破坏性操作。
- 绝不假设合成处于活动状态而不检查。
- 绝不使用 cat > file << 'SCRIPT' heredoc 编写脚本 — 改用 Write 工具,然后用简短 bash 命令执行。