自动化
通过在 xiantong 应用和 Agent 事件上触发操作来自动化工作流程
通过在 xiantong 的应用和 Agent 事件上触发操作来自动化工作流程
只需告诉 xiantong。 说诸如“创建一个在会话被标记时通知我的自动化”或“每天下午 9 点设置每日早报”之类的话。xiantong 会为你创建并验证配置。
自动化让你在 xiantong 中事件发生时自动触发操作。你可以运行 shell 命令、发送提示以启动新会话,或安排定期工作流——所有这些都在一个 JSON 文件中配置。
开始使用#
设置自动化最简单的方法就是用自然语言描述你的需求。你可以尝试以下提示:
| 你想要的 | 你可以这样说 |
|---|---|
| 定时简报 | “设置一个每个工作日 9 点的每日例会简报” |
| 桌面通知 | “当某个会话被标记为 urgent 时,用 macOS 通知提醒我” |
| 审计日志 | “将所有权限模式更改记录到文件中” |
| 自动打标签 | “会话启动时,运行一个命令检查工作目录并记录下来” |
| 定期报告 | “每周五下午 5 点创建一个总结本周已完成任务的会话” |
| Webhook 集成 | “当我标记某个会话时,向我的 webhook URL 发送 curl 请求” |
你的第一个自动化#
这里是最简单的自动化:每当会话添加标签时,它就记录一条消息:
{
"version": 2,
"automations": {
"LabelAdd": [
{
"actions": [
{ "type": "command", "command": "echo \"Label added: $XIANTONG_LABEL\" >> ~/xiantong-automations.log" }
]
}
]
}
}
将其保存为 ~/.xiantong/workspaces/{workspaceId}/automations.json,它会立即生效——无需重启。
安排提示#
想让 xiantong 按计划为你执行某些操作?使用带有 cron 表达式的提示操作:
{
"version": 2,
"automations": {
"SchedulerTick": [
{
"cron": "0 9 * * 1-5",
"timezone": "America/New_York",
"labels": ["Scheduled"],
"actions": [
{ "type": "prompt", "prompt": "检查 @github 是否有新的分配给我的 issue 并总结它们" }
]
}
]
}
}
这会在每个工作日的 上午 9 点创建一个新会话,激活 GitHub 源,并让 xiantong 检查你的 issue。该会话会自动标记为 “Scheduled” 以便快速过滤。
自动化如何工作#
当事件触发(例如添加了标签、工具运行或 cron 匹配)时,xiantong 会检查你的配置以匹配项并执行它们。有两种操作类型:
- 命令操作 — 执行 shell 命令,事件数据作为环境变量提供
- 提示操作 — 将提示发送给 xiantong,创建新会话(仅适用于应用事件)
配置文件#
每个工作区在 automations.json 中配置自动化:
~/.xiantong/workspaces/{workspaceId}/automations.json
基本结构#
{
"version": 2,
"automations": {
"EventName": [
{
"matcher": "regex-pattern",
"actions": [
{ "type": "command", "command": "echo 'Hello'" }
]
}
]
}
}
每种事件类型对应一个匹配器数组,每个匹配器包含事件值匹配时要执行的操作数组。
管理自动化#
在 UI 中#
自动化在侧边栏的 Automations 下列出。在这里你可以:
- 启用 / 禁用 — 在不删除的情况下切换单个自动化的状态
- 复制 — 创建已有自动化的副本,名称带 “Copy” 后缀
- 删除 — 永久移除自动化
- 测试 — 手动触发自动化,在等待实际事件前验证其是否有效。测试运行器会解析
@mentions、启用源并使用已配置的llmConnection/model—— 与调度器走的是相同代码路径。 - 执行历史 — 每条自动化记录成功与失败,可在详情页查看时间线。历史存储在
automations-history.jsonl中,最多保留每条自动化最近 20 次运行(总共最多 1000 条记录)。
支持批量操作——选择多个自动化后可一起启用、禁用或删除。列表按最近执行时间排序,便于快速访问活跃自动化。
在配置文件中#
你也可以直接编辑 automations.json 管理自动化。更改立即生效——无需重新启动。启用与禁用: 在任意匹配器上设置 "enabled": false 可暂时禁用它而不删除配置。省略该字段或设为 true 即可重新启用。
{
"matcher": "^urgent$",
"enabled": false,
"actions": [
{ "type": "command", "command": "notify-send 'Urgent!'" }
]
}
删除: 从 automations.json 中移除匹配器条目。如果某事件类型下不再有匹配器,可以移除整个事件键。
让你的 xiantong Agent 帮你管理自动化:“禁用我所有的定时自动化”或“移除紧急通知自动化”。xiantong 会直接读取并更新 automations.json。
事件#
应用事件#
由 xiantong 自身触发。支持命令与提示操作。
| 事件 | 触发条件 | 匹配值 |
|---|---|---|
LabelAdd | 会话添加标签时 | 标签 ID(例如 urgent) |
LabelRemove | 会话移除标签时 | 标签 ID |
LabelConfigChange | 标签配置更改时 | 始终匹配 |
PermissionModeChange | 权限模式更改时 | 新模式名称 |
FlagChange | 会话被标记或取消标记时 | true 或 false |
SessionStatusChange | 会话状态变更时 | 新状态名称(例如 done) |
SchedulerTick | 每分钟运行一次 | 使用 cron 匹配 |
重命名: TodoStateChange 已重命名为 SessionStatusChange。旧名称仍可用但会显示验证警告。建议将所有自动化更新为 SessionStatusChange。
状态变更: 若想响应状态/工作流状态变化(例如会话转为 “done” 或 “in-progress”),可使用 SessionStatusChange 事件。匹配值是新状态名称,因此你可以使用 "^done$" 之类的匹配器仅在特定迁移触发时生效。
Agent 事件#
传递给 Claude SDK。仅支持命令操作(不支持提示操作)。
| 事件 | 触发条件 | 匹配值 |
|---|---|---|
PreToolUse | 工具执行前 | 工具名称 |
PostToolUse | 工具成功后 | 工具名称 |
PostToolUseFailure | 工具失败后 | 工具名称 |
UserPromptSubmit | 用户提交提示时 | 事件数据 JSON |
SessionStart | 会话开始 | 事件数据 JSON |
SessionEnd | 会话结束 | 事件数据 JSON |
Stop | Agent 停止 | 事件数据 JSON |
SubagentStart | 子 Agent 启动 | 事件数据 JSON |
SubagentStop | 子 Agent 完成 | 事件数据 JSON |
Notification | 接收到通知 | 事件数据 JSON |
PreCompact | 上下文压缩前 | 事件数据 JSON |
PermissionRequest | 请求权限 | 事件数据 JSON |
Setup | Agent 初始化 | 事件数据 JSON |
操作类型#
命令操作#
事件触发时执行 shell 命令。事件数据可通过环境变量访问。
{
"type": "command",
"command": "echo \"标签 $XIANTONG_LABEL 已添加\" >> ~/automation-log.txt",
"timeout": 60000
}
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
type | "command" | 必需 | 操作类型 |
command | string | 必需 | 要执行的 shell 命令 |
timeout | number | 60000 | 超时时间(毫秒) |
提示操作#
将提示发送给 xiantong,创建新会话。仅适用于应用事件。
{
"type": "prompt",
"prompt": "运行 @weather 技能并总结今天的天气预报"
}
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
type | "prompt" | 必需 | 操作类型 |
prompt | string | 必需 | 要发送的提示文本 |
llmConnection | string | 工作区默认 | LLM 连接 slug(在 AI 设置中配置) |
model | string | 工作区默认 | 为创建的会话指定的模型 ID |
特点:
- 使用
@mentions引用源或技能(例如@github、@linear) - 环境变量会展开(例如
$XIANTONG_LABEL、${XIANTONG_SESSION_NAME}) - 被提及的源会自动为新会话启用
LLM 连接与模型: 你可以指定提示操作创建的会话使用哪个 AI 提供商和模型。如果省略,则使用工作区默认连接与模型。
{
"type": "prompt",
"prompt": "对最近的更改进行快速代码审查",
"llmConnection": "my-copilot-connection",
"model": "gemini-3-pro-preview"
}
llmConnection 的值是 AI 设置中配置的 LLM 连接 slug。model 是该提供商支持的模型 ID。如果任一无效或找不到,系统会优雅地回退至工作区默认配置。
匹配器#
正则匹配#
大多数事件会针对事件的匹配值执行正则匹配:
{
"matcher": "^urgent$",
"actions": [
{ "type": "command", "command": "notify-send 'Urgent!'" }
]
}
省略 matcher 字段即可匹配该类型的所有事件。示例:
| 模式 | 匹配内容 |
|---|---|
^urgent$ | 与 “urgent” 完全匹配 |
bug|feature | 匹配 “bug” 或 “feature” |
^prod- | 匹配以 “prod-” 开头的任意值 |
| (省略) | 匹配该类型的所有事件 |
Cron 匹配#
对于 SchedulerTick 事件,请使用 cron 表达式而非正则:
{
"cron": "0 9 * * 1-5",
"timezone": "Europe/Budapest",
"actions": [
{ "type": "prompt", "prompt": "给我一个早间简报" }
]
}
Cron 格式: 分钟 小时 月内日 月 星期
| 字段 | 范围 | 示例 |
|---|---|---|
| 分钟 | 0–59 | 0、*/15 |
| 小时 | 0–23 | 9、14 |
| 月内日 | 1–31 | 1、15 |
| 月 | 1–12 | 1、*/3 |
| 星期 | 0–6(0 = 周日) | 1-5、0,6 |
常见模式:
| Cron | 计划 |
|---|---|
*/15 * * * * | 每 15 分钟一次 |
0 9 * * * | 每天 9:00 |
0 9 * * 1-5 | 工作日 9:00 |
30 14 1 * * | 每月 1 日 14:30 |
0 */6 * * * | 每 6 小时一次 |
时区: 使用 IANA 时区名称(例如 Europe/Budapest、America/New_York)。如果未指定,则默认使用系统时区。可通过 crontab.guru 进行验证。
条件#
条件是可选的筛选器,在匹配器/cron 匹配后但在执行操作前运行。数组中的所有条件必须通过(隐含的 AND)。如果数组为空或省略,则无条件地执行操作。
条件可组合——你可以结合时间窗口、星期过滤和状态检查,从而在无需复杂 cron 的情况下构建精确的自动化触发逻辑。
{
"cron": "0 9 * * *",
"timezone": "Europe/Budapest",
"conditions": [
{
"condition": "time",
"weekday": ["mon", "tue", "wed", "thu", "fri"]
}
],
"actions": [
{ "type": "prompt", "prompt": "早安!这是你的每日简报。" }
]
}
时间条件#
检查指定时区中的时间和星期:
{
"condition": "time",
"after": "09:00",
"before": "17:00",
"weekday": ["mon", "tue", "wed", "thu", "fri"],
"timezone": "Europe/Budapest"
}
| 属性 | 类型 | 说明 |
|---|---|---|
after | "HH:MM" | 时间窗口开始(包含) |
before | "HH:MM" | 时间窗口结束(排除) |
weekday | string[] | 允许的星期:mon、tue、wed、thu、fri、sat、sun |
timezone | string | IANA 时区。若未设置,则依次回退至匹配器时区,再回退至系统本地时区 |
过夜范围: 如果 after 晚于 before(例如 "after": "22:00", "before": "06:00"),则时间段会跨越午夜。
状态条件#
检查事件载荷中的字段,用于筛选特定的迁移或值:
{
"condition": "state",
"field": "permissionMode",
"from": "safe",
"to": "allow-all"
}
| 属性 | 类型 | 说明 |
|---|---|---|
field | string | 载荷字段名(例如 permissionMode、sessionStatus、labels、isFlagged) |
value | any | 精确匹配 |
from | any | 旧值(用于迁移事件) |
to | any | 新值(用于迁移事件) |
contains | string | 数组成员检查(例如判断标签是否存在) |
not_value | any | 匹配除该值以外的任意值 |
迁移字段: 对于 permissionMode 与 sessionStatus,from/to 会自动解析为正确的载荷键(分别为 oldMode/newMode、oldState/newState)。
逻辑组合#
使用 and、or、not 组合条件:
{
"condition": "and",
"conditions": [
{ "condition": "time", "weekday": ["mon", "tue", "wed", "thu", "fri"] },
{ "condition": "time", "after": "09:00", "before": "17:00" }
]
}
{
"condition": "or",
"conditions": [
{ "condition": "state", "field": "permissionMode", "value": "allow-all" },
{ "condition": "state", "field": "isFlagged", "value": true }
]
}
{
"condition": "not",
"conditions": [
{ "condition": "time", "weekday": ["sat", "sun"] }
]
}
| 类型 | 行为 |
|---|---|
and | 所有子条件必须通过 |
or | 至少一个子条件通过 |
not | 所有子条件都必须不通过 |
条件最多可嵌套 8 层。达到第 4 层时会发出简化警告。请尽量保持结构扁平。未知的条件类型会闭合失败(结果为 false)。
匹配器选项#
每个匹配器条目都支持以下可选字段:
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
matcher | string | 匹配所有 | 事件过滤的正则模式 |
cron | string | — | Cron 表达式(仅限 SchedulerTick) |
timezone | string | 系统时区 | Cron 的 IANA 时区 |
conditions | array | [] | 所有条件必须在执行操作前通过(参见 条件) |
permissionMode | string | "safe" | 命令的安全模式 |
labels | string[] | [] | 为提示创建的会话附加的标签 |
enabled | boolean | true | 设置为 false 可在不删除的情况下禁用 |
actions | array | 必需 | 命令/提示操作数组 |
环境变量#
通用变量#
所有命令操作都可访问:
| 变量 | 说明 |
|---|---|
XIANTONG_EVENT | 事件名称(例如 LabelAdd、PreToolUse) |
XIANTONG_EVENT_DATA | 完整事件载荷(JSON) |
XIANTONG_SESSION_ID | 当前会话 ID |
XIANTONG_SESSION_NAME | 当前会话名称 |
XIANTONG_WORKSPACE_ID | 当前工作区 ID |
应用事件变量#
从事件载荷动态生成:
标签事件(LabelAdd、LabelRemove):
XIANTONG_LABEL— 被添加/移除的标签 ID
PermissionModeChange:
XIANTONG_OLD_MODE— 之前的权限模式XIANTONG_NEW_MODE— 新的权限模式
FlagChange:
XIANTONG_IS_FLAGGED—true或false
SessionStatusChange:
XIANTONG_OLD_STATE— 之前的会话状态XIANTONG_NEW_STATE— 新的会话状态
SchedulerTick:
XIANTONG_LOCAL_TIME— 当前时间(HH:MM)XIANTONG_LOCAL_DATE— 当前日期(YYYY-MM-DD)
Agent 事件变量#
工具事件(PreToolUse、PostToolUse、PostToolUseFailure):
XIANTONG_TOOL_NAME— 正在使用的工具XIANTONG_TOOL_INPUT— 工具参数(JSON)XIANTONG_TOOL_RESPONSE— 工具输出(仅限 PostToolUse)XIANTONG_ERROR— 错误信息(仅限 PostToolUseFailure)
会话事件(SessionStart):
XIANTONG_SOURCE— 会话来源(例如startup、resume)XIANTONG_MODEL— 模型名称
子 Agent 事件(SubagentStart、SubagentStop):
XIANTONG_AGENT_ID— 子 Agent IDXIANTONG_AGENT_TYPE— 子 Agent 类型
权限模式#
命令操作默认经过安全检查。可在每个匹配器中调整:
| 模式 | 行为 | 使用场景 |
|---|---|---|
safe | 命令基于白名单进行检查 | 默认推荐 |
allow-all | 绕过安全检查 | 仅限受信任的自动化 |
仅在完全信任命令时使用 allow-all,它允许执行任意 shell 命令。
{
"matcher": "^urgent$",
"permissionMode": "allow-all",
"actions": [
{ "type": "command", "command": "osascript -e 'display notification \"紧急会话已标记\" with title \"xiantong\"'" }
]
}
提示操作的标签#
提示操作可以为它们创建的会话附带标签,方便过滤与整理定时会话:
{
"cron": "0 9 * * *",
"labels": ["Scheduled", "morning-briefing"],
"actions": [
{ "type": "prompt", "prompt": "告诉我今天的重点事项" }
]
}
标签也支持环境变量展开:"priority::${XIANTONG_LABEL}"。
速率限制#
为防止自动化之间形成死循环(例如一个自动化间接触发自身),事件总线实施了速率限制:
| 事件 | 最大每分钟触发次数 |
|---|---|
SchedulerTick | 60(每秒 1 次) |
| 其他所有事件 | 10 |
超出限制的事件在剩余 60 秒窗口中会被静默丢弃。
示例#
每日早间简报#
在每个工作日的上午 9 点安排一个提示:
{
"version": 2,
"automations": {
"SchedulerTick": [
{
"cron": "0 9 * * 1-5",
"timezone": "Europe/Budapest",
"labels": ["Scheduled", "briefing"],
"actions": [
{ "type": "prompt", "prompt": "运行 @daily-standup 技能" }
]
}
]
}
}
仅限工作日的 AI 新闻(含条件)#
使用 time 条件把每日计划限定为工作日:
{
"version": 2,
"automations": {
"SchedulerTick": [
{
"name": "早间 AI 新闻",
"cron": "0 9 * * *",
"timezone": "Europe/Budapest",
"conditions": [
{
"condition": "time",
"weekday": ["mon", "tue", "wed", "thu", "fri"],
"timezone": "Europe/Budapest"
}
],
"labels": ["Scheduled", "ai-news"],
"actions": [
{ "type": "prompt", "prompt": "运行 @ai-news 技能并总结当天的 AI 发展" }
]
}
]
}
}
权限模式闸门(含条件)#
仅在权限模式从 safe 变为 allow-all 时通知:
{
"version": 2,
"automations": {
"PermissionModeChange": [
{
"conditions": [
{
"condition": "state",
"field": "permissionMode",
"from": "safe",
"to": "allow-all"
}
],
"actions": [
{ "type": "command", "command": "osascript -e 'display notification \"权限已升级至 allow-all\" with title \"xiantong\"'" }
]
}
]
}
}
记录标签变化#
追踪标签的添加与移除:
{
"version": 2,
"automations": {
"LabelAdd": [
{
"permissionMode": "allow-all",
"actions": [
{ "type": "command", "command": "echo \"[$(date)] 添加: $XIANTONG_LABEL\" >> ~/label-log.txt" }
]
}
],
"LabelRemove": [
{
"permissionMode": "allow-all",
"actions": [
{ "type": "command", "command": "echo \"[$(date)] 移除: $XIANTONG_LABEL\" >> ~/label-log.txt" }
]
}
]
}
}
标记为 urgent 时的 macOS 通知#
{
"version": 2,
"automations": {
"LabelAdd": [
{
"matcher": "^urgent$",
"permissionMode": "allow-all",
"actions": [
{
"type": "command",
"command": "osascript -e 'display notification \"紧急会话被标记\" with title \"xiantong\"'"
}
]
}
]
}
}
审计权限模式变化#
{
"version": 2,
"automations": {
"PermissionModeChange": [
{
"permissionMode": "allow-all",
"actions": [
{
"type": "command",
"command": "echo \"$(date): $XIANTONG_OLD_MODE -> $XIANTONG_NEW_MODE\" >> ~/mode-audit.log"
}
]
}
]
}
}
不同时间段的多个计划并开启/关闭控制#
在不同时间运行多个自动化,并可在不删除的情况下禁用某些项:
{
"version": 2,
"automations": {
"SchedulerTick": [
{
"cron": "0 9 * * 1-5",
"timezone": "Europe/Budapest",
"labels": ["Scheduled"],
"actions": [
{ "type": "prompt", "prompt": "给我一个早间简报" }
]
},
{
"cron": "0 17 * * 5",
"timezone": "Europe/Budapest",
"enabled": false,
"labels": ["Scheduled"],
"actions": [
{ "type": "prompt", "prompt": "总结本周已完成的任务" }
]
}
]
}
}
第二条自动化(周五总结)被禁用,直到将 "enabled" 设置为 true 或移除它。
使用特定 LLM 连接的提示#
为某个自动化指定不同的 AI 提供商:
{
"version": 2,
"automations": {
"SchedulerTick": [
{
"cron": "0 8 * * 1-5",
"timezone": "Europe/Budapest",
"labels": ["Scheduled"],
"actions": [
{
"type": "prompt",
"prompt": "回顾夜间 @github 的拉取请求",
"llmConnection": "openrouter",
"model": "anthropic/claude-sonnet-4.6"
}
]
}
]
}
}
验证#
让 xiantong 验证你的自动化:
Validate my automations configuration
或使用 config_validate 工具,target: "all"。验证器检查以下内容:
- 无效的 JSON 语法
- 未知的事件名称
- 空的操作数组
- 无效的 cron 表达式或时区
- 无效或不安全的正则模式(防范 ReDoS)
- 引用不存在的标签
- 无效的条件类型、字段名或星期值
- 条件嵌套层数超过限制
- 缺失的
llmConnectionslug(错误 —— 运行时会失败) - 同时指定了
llmConnection与model时,模型/提供商不匹配(警告)
安全#
自动化包含多个内置安全措施:
- 防止 shell 注入 —— 环境变量中的用户可控值(会话名、标签、提示文本)会自动进行转义
- 防范 ReDoS —— 正则长度限制为 500 字符,并检测灾难性回溯模式
- 速率限制 —— 防止自动化触发其他自动化导致无限循环
- 权限模式 —— 默认情况下命令会经过白名单检查
- 超时 —— 命令在超时后终止(若需要会发送 SIGKILL)
最佳实践#
- 从简单开始 —— 用
echo命令测试,再编写复杂脚本 - 使用标签 —— 为定时会话打标以便快速过滤
- 设置超时 —— 用
timeout字段避免命令失控 - 记录失败 —— 将 stderr 重定向用于追踪问题:
command 2>> ~/automation-errors.log - 精确匹配 —— 使用匹配器避免每个事件都触发
- 验证 cron —— 用 crontab.guru 确认表达式
- 使用
enabled: false—— 调试时可暂时禁用自动化而不是删除
故障排查:自动化未触发#
- 检查事件名称 —— 必须完全匹配(例如
LabelAdd,不要写成labeladd) - 检查匹配器 —— 正则必须与事件的匹配值匹配
- 检查 cron —— SchedulerTick 时确认 cron 表达式是否正确
- 检查启用状态 —— 确认匹配器没有
"enabled": false - 检查日志 —— 查看应用日志中带有
[automations]的记录
故障排查:命令被阻止#
如果看到 “Bash command blocked” 错误:
- 在匹配器中添加
"permissionMode": "allow-all" - 或简化命令,避免使用如
$()的复杂 shell 构造
故障排查:提示未创建会话#
- 确保事件属于 应用事件(提示操作不适用于 Agent 事件)
- 检查提示文本非空
- 确认
@mentions引用了有效的源或技能
故障排查:条件未匹配#
- 检查星期拼写 —— 必须是 3 个字母的小写:
mon、tue、wed、thu、fri、sat、sun - 检查时区 —— 使用 IANA 名称(例如
Europe/Budapest)。无效时区会静默回退到系统本地时区 - 检查时间格式 —— 必须是 24 小时制的
HH:MM(例如09:00,不要写成9:00 AM) - 检查状态字段名 —— 使用
permissionMode、sessionStatus、labels、isFlagged - 检查嵌套深度 —— 嵌套超过 8 层的条件总是评估为 false
- 检查日志 —— 查看带有
[automations]的日志条目,了解条件评估情况