@swifty.js/swifty 0.0.1 → 0.0.2
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.
- package/README.md +183 -0
- package/dist/agent-MICFDGUF.js +4 -0
- package/dist/anthropic-JDAGNAPR.js +4 -0
- package/dist/checker-PF3FEOF2.js +4 -0
- package/dist/chunk-4KVSJNS6.js +90 -0
- package/dist/chunk-6ARDOHBL.js +4 -0
- package/dist/chunk-7MHXMDYC.js +35 -0
- package/dist/chunk-F6HLYUZ4.js +355 -0
- package/dist/chunk-FZPTNGTU.js +4 -0
- package/dist/chunk-LPLPMGWW.js +336 -0
- package/dist/chunk-MQ5XOYLD.js +4 -0
- package/dist/chunk-RD3MICOU.js +4 -0
- package/dist/{cleanup-4R3534Z3.js → cleanup-BQJDUOKA.js} +1 -1
- package/dist/glob_addon.node +0 -0
- package/dist/main.js +240 -240
- package/dist/openai-I4WTRNNT.js +26 -0
- package/dist/{server-XPKSROM2.js → server-OGPKL2U2.js} +22 -21
- package/package.json +17 -24
- package/dist/anthropic-737END4X.js +0 -4
- package/dist/chunk-NCPOPA4A.js +0 -4
- package/dist/chunk-SC34YHMX.js +0 -521
- package/dist/chunk-Z3E5YV3P.js +0 -121
- package/dist/openai-4KX74QBZ.js +0 -27
- package/docs/ch1.md +0 -25
- package/docs/ch10.md +0 -122
- package/docs/ch11.md +0 -163
- package/docs/ch12.md +0 -289
- package/docs/ch13.md +0 -320
- package/docs/ch14.md +0 -152
- package/docs/ch15.md +0 -547
- package/docs/ch2.md +0 -273
- package/docs/ch3.md +0 -206
- package/docs/ch4.md +0 -125
- package/docs/ch5.md +0 -165
- package/docs/ch6.md +0 -201
- package/docs/ch7.md +0 -448
- package/docs/ch8.md +0 -217
- package/docs/ch9.md +0 -351
- package/docs/index.css +0 -23
- package/docs/index.md +0 -21
- package/docs/swifty.mdx +0 -7
package/docs/ch11.md
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
# Skill
|
|
2
|
-
|
|
3
|
-
skill 是写给 AI 的 SOP (Standard Operation Procedure)
|
|
4
|
-
|
|
5
|
-
背景: ch10 的 Slash Command 中, prompt 类型的命令可以将硬编码的代码审查 prompt 发送给 LLM, 不独立、不可更新、不可移植
|
|
6
|
-
|
|
7
|
-
1. skill 是独立、可 (热) 更新、可移植
|
|
8
|
-
2. 可以显式指定 skill, 提高 LLM 的准确率
|
|
9
|
-
3. skill 可以携带资产:
|
|
10
|
-
- SKILL.md: SOP
|
|
11
|
-
- API reference、docs、example、scripts
|
|
12
|
-
4. 执行模式: inline 或 fork
|
|
13
|
-
5. 参数 $ARGUMENTS
|
|
14
|
-
|
|
15
|
-
## Frontmatter
|
|
16
|
-
|
|
17
|
-
```md
|
|
18
|
-
---
|
|
19
|
-
name: skill-creator <!-- 不能和 Slash Comment 重名 -->
|
|
20
|
-
description: Create new skills...
|
|
21
|
-
allowed_tools: [] <!-- 可选的, 指定 skill 的工具白名单 -->
|
|
22
|
-
mode: skill 执行模式, inline 或 fork
|
|
23
|
-
model: 可选的, 指定 skill 使用的模型
|
|
24
|
-
fork_context: 可选的, 仅在 mode: fork 时生效, 决定携带的上下文; 可以是 full 对话摘要、recent 最近的 5 条消息、none 不携带对话历史; inline 模式共享对话历史, fork_context 字段会被静默忽略 <!-- 源码: src/skills/catalog.ts -->
|
|
25
|
-
---
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## skills 目录, 优先级从高到低
|
|
29
|
-
|
|
30
|
-
1. 项目级: ${workDir}/.swifty/skills/
|
|
31
|
-
2. 用户级: ~/.swifty/skills
|
|
32
|
-
3. 内置级: Swifty 内置的 skills
|
|
33
|
-
|
|
34
|
-
## skill 执行模式
|
|
35
|
-
|
|
36
|
-
### inline 模式
|
|
37
|
-
|
|
38
|
-
默认执行模式, 内联 skill 的 prompt 到用户消息, 参与 agent loop
|
|
39
|
-
|
|
40
|
-
### fork 模式
|
|
41
|
-
|
|
42
|
-
开启新对话, 调用 LLM API, 只将 LLM API 的响应返回给主对话, 不参与 agent loop
|
|
43
|
-
|
|
44
|
-
fork 模式的实现:
|
|
45
|
-
|
|
46
|
-
- 开启新对话
|
|
47
|
-
- 根据 skill.fork_context
|
|
48
|
-
- full 压缩上下文, 生成对话摘要, 携带对话摘要
|
|
49
|
-
- recent 携带最近的 5 条消息
|
|
50
|
-
- none 不携带对话历史 (默认)
|
|
51
|
-
- 如果用户传递参数, 则替换或追加 skill prompt 中的参数 $ARGUMENTS
|
|
52
|
-
- 使用 skill.model 创建一个临时 Agent, 拿到 LLM API 的响应
|
|
53
|
-
- 将 LLM API 的响应作为 assistant 消息返回给主对话
|
|
54
|
-
|
|
55
|
-
## `$ARGUMENTS`
|
|
56
|
-
|
|
57
|
-
```md
|
|
58
|
-
请审查以下代码变更
|
|
59
|
-
$ARGUMENTS
|
|
60
|
-
如果没有指定代码审查范围, 请审查 `git diff` 的所有变更
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
用户输入 `/review 重点关注类型问题` (replaceAll 字符串替换)
|
|
64
|
-
|
|
65
|
-
```md
|
|
66
|
-
请审查以下代码变更
|
|
67
|
-
重点关注类型问题
|
|
68
|
-
如果没有指定代码审查范围, 请审查 `git diff` 的所有变更
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
fork 模式
|
|
72
|
-
|
|
73
|
-
如果用户有输入, 则在 prompt 末尾追加 `\n\nARGUMENTS: ${args}`
|
|
74
|
-
|
|
75
|
-
## 自动注册为 Slash Command (prompt 命令)
|
|
76
|
-
|
|
77
|
-
skill 加载后自动注册为 Slash Command (prompt 命令)
|
|
78
|
-
|
|
79
|
-
热加载: 每次使用 skill 时都重新读文件
|
|
80
|
-
|
|
81
|
-
## 意图识别: 让 Agent 自己选择 skill
|
|
82
|
-
|
|
83
|
-
### 两阶段加载
|
|
84
|
-
|
|
85
|
-
第一阶段: 轻量启动
|
|
86
|
-
|
|
87
|
-
Swifty 启动时, 扫描 skills 目录, 加载所有 skill 的 frontmatter 元信息 (name, description), 不加载完整 prompt 正文, 将 skill 元信息注入到 system prompt, 告诉 LLM 有哪些 skill
|
|
88
|
-
|
|
89
|
-
第二阶段: 按需加载
|
|
90
|
-
|
|
91
|
-
LLM 判断用户意图匹配某个 skill 时, 调用 LoadSkill 工具
|
|
92
|
-
|
|
93
|
-
LoadSkill 工具根据该 skill 的 name, 读取 SKILL.md 的 SOP 作为工具调用结果返回, LLM 在下一轮 agent loop turn 中可以看到该 skill 的 SOP
|
|
94
|
-
|
|
95
|
-
### LoadSkill
|
|
96
|
-
|
|
97
|
-
- properties: name
|
|
98
|
-
- metadata: 只读、非破坏性、分类 read
|
|
99
|
-
|
|
100
|
-
```js
|
|
101
|
-
function LoadSkill(name) {
|
|
102
|
-
const skill = this.catalog.get(name);
|
|
103
|
-
if (!skill) {
|
|
104
|
-
return {
|
|
105
|
-
output: `Skill '${name}' not found. Available skills: ${available}`,
|
|
106
|
-
isError: true,
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
const body = runInline(skill, "", this.host);
|
|
110
|
-
// 记录已激活
|
|
111
|
-
// 用于上下文压缩, CLI 侧压缩恢复, 恢复关键上下文 skills
|
|
112
|
-
return {
|
|
113
|
-
output: `Skill '${name}' activated.\n\n${body}`,
|
|
114
|
-
isError: false,
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
## 渐进式披露
|
|
120
|
-
|
|
121
|
-
渐进式披露: Agent 启动时, 扫描 skills 目录, 加载所有 skill 的 frontmatter 元信息 (name, description), 选择压力很低, LLM 判断用户意图匹配某个 skill 时, 才加载完整 SOP, 注意力集中在当前任务
|
|
122
|
-
|
|
123
|
-
## 目录型 skill
|
|
124
|
-
|
|
125
|
-
- 单文件 skill 只有 SOP
|
|
126
|
-
- 目录型 skill 可以携带资产: SOP、API reference、docs、example、scripts, 整套技能方便打包、移植
|
|
127
|
-
|
|
128
|
-
```txt
|
|
129
|
-
$ tree ~/.claude/skills/skill-creator
|
|
130
|
-
.claude/skills/skill-creator
|
|
131
|
-
├── agents
|
|
132
|
-
│ └── xxx.md
|
|
133
|
-
├── assets
|
|
134
|
-
│ └── xxx.html
|
|
135
|
-
├── docs
|
|
136
|
-
│ └── ...
|
|
137
|
-
├── example
|
|
138
|
-
│ └── xxx.md
|
|
139
|
-
├── LICENSE.txt
|
|
140
|
-
├── references
|
|
141
|
-
│ └── xxx.md
|
|
142
|
-
├── scripts
|
|
143
|
-
│ ├── xxx.py
|
|
144
|
-
│ └── yyy.py
|
|
145
|
-
└── SKILL.md
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
## 完整流程
|
|
149
|
-
|
|
150
|
-
```txt
|
|
151
|
-
1. 启动时扫描 skills 目录, 加载所有 skill 的 frontmatter 元信息 (name, description), 轻量启动
|
|
152
|
-
2. 将 skill 元信息注入到 system prompt, 告诉 LLM 有哪些 skill
|
|
153
|
-
3. skill 加载后自动注册为 Slash Command (prompt 命令)
|
|
154
|
-
4. 用户输入: 做一个 react 计数器 app
|
|
155
|
-
5. 意图识别: LLM 判断匹配 react-best-practices skill
|
|
156
|
-
6. Agent 请求调用工具 LoadSkill("react-best-practices")
|
|
157
|
-
7. SOP 作为工具调用结果返回, 注入到 messages
|
|
158
|
-
8. LLM 按 SKILL.md 的 critical/high/medium/low 规则、进行开发
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
- MCP 负责接入
|
|
162
|
-
- 工具调用负责调用
|
|
163
|
-
- skill 负责编排工作流
|
package/docs/ch12.md
DELETED
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
# Hook
|
|
2
|
-
|
|
3
|
-
在 Agent 的生命周期事件上挂载自动化动作
|
|
4
|
-
|
|
5
|
-
## Hook 的三要素
|
|
6
|
-
|
|
7
|
-
- 事件
|
|
8
|
-
- 条件, 可以省略, 如果省略则无条件触发
|
|
9
|
-
- 动作
|
|
10
|
-
|
|
11
|
-
配置:
|
|
12
|
-
|
|
13
|
-
- ~/.swifty/config.yaml
|
|
14
|
-
- ${projectRoot}/.swifty/config.yaml
|
|
15
|
-
- ${projectRoot}/.swifty/config.local.yaml
|
|
16
|
-
|
|
17
|
-
3 个配置文件按顺序加载, 后加载的 hook 配置不会覆盖先加载的 hook 配置, 多个 hook 配置会被拼接; 一个事件有多个 hook 时, 按 yaml 中的顺序逐个执行
|
|
18
|
-
|
|
19
|
-
<!-- 源码: src/config/config.ts HookConfigSchema -->
|
|
20
|
-
|
|
21
|
-
```yaml
|
|
22
|
-
hooks:
|
|
23
|
-
- event: post_tool_use
|
|
24
|
-
condition: tool == "WriteFile"
|
|
25
|
-
action:
|
|
26
|
-
type: command
|
|
27
|
-
command: "prettier -w $SWIFTY_FILE_PATH"
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
<!-- 源码: src/hooks/hooks.ts 环境变量 SWIFTY_EVENT, SWIFTY_TOOL, SWIFTY_FILE_PATH -->
|
|
31
|
-
|
|
32
|
-
每当 Agent 调用 WriteFile 工具写文件后, 自动 format 代码
|
|
33
|
-
|
|
34
|
-
- 事件: post_tool_use
|
|
35
|
-
- 条件: tool == "WriteFile"
|
|
36
|
-
- 动作: format 代码
|
|
37
|
-
|
|
38
|
-
## 事件
|
|
39
|
-
|
|
40
|
-
<!-- 源码: src/hooks/hooks.ts EventName 类型定义 -->
|
|
41
|
-
|
|
42
|
-
### 会话级
|
|
43
|
-
|
|
44
|
-
- session_start 会话开始时触发
|
|
45
|
-
- session_end 会话结束时触发
|
|
46
|
-
|
|
47
|
-
### Agent Loop 轮次级
|
|
48
|
-
|
|
49
|
-
- turn_start 用户发送新消息时触发, 一轮对话开始
|
|
50
|
-
- turn_end LLM 退出 agent loop 时触发, 一轮对话结束
|
|
51
|
-
- LLM 决定退出循环
|
|
52
|
-
- 超过最大循环次数后强制退出循环
|
|
53
|
-
- 用户按 esc 退出循环
|
|
54
|
-
|
|
55
|
-
### 工具级
|
|
56
|
-
|
|
57
|
-
- pre_tool_use 工具调用前触发, 可以拦截工具调用
|
|
58
|
-
- post_tool_use 工具调用后触发
|
|
59
|
-
|
|
60
|
-
### 消息级
|
|
61
|
-
|
|
62
|
-
- pre_send 用户消息发送给 LLM API 前触发
|
|
63
|
-
- post_receive 收到 LLM API 响应后触发
|
|
64
|
-
|
|
65
|
-
### 系统级
|
|
66
|
-
|
|
67
|
-
- startup: Swifty 启动时触发
|
|
68
|
-
- shutdown: Swifty 退出时触发
|
|
69
|
-
- error: Swifty 发生错误时触发
|
|
70
|
-
- compact: 上下文压缩时触发
|
|
71
|
-
- permission_request: 权限请求时触发
|
|
72
|
-
- file_change: 文件被修改时触发
|
|
73
|
-
- command_execute: Slash Command 执行时触发
|
|
74
|
-
|
|
75
|
-
## pre_tool_use
|
|
76
|
-
|
|
77
|
-
```yaml
|
|
78
|
-
hooks:
|
|
79
|
-
- event: pre_tool_use
|
|
80
|
-
condition: 'tool == "WriteFile" && path == "pnpm-lock.yaml"'
|
|
81
|
-
action:
|
|
82
|
-
type: command
|
|
83
|
-
command: "echo 'Never manually edit pnpm-lock.yaml'"
|
|
84
|
-
reject: true
|
|
85
|
-
|
|
86
|
-
- event: pre_tool_use
|
|
87
|
-
condition: 'tool == "Bash" && command =~ "rm\\s+-rf\\s+\\/"'
|
|
88
|
-
action:
|
|
89
|
-
type: command
|
|
90
|
-
command: "echo 'Dangerous rm command detected'"
|
|
91
|
-
reject: true
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
<!-- 源码: src/hooks/hooks.ts -->
|
|
95
|
-
|
|
96
|
-
reject: true 是 pre_tool_use 事件的特殊字段, reject: true 时, 工具调用被拒绝, CLI 将 hook 抛出的错误 reason 作为工具调用结果 `{ content: reason, isError: true }` 返回给 LLM, LLM 调整策略
|
|
97
|
-
|
|
98
|
-
pre_tool_use 事件的动作默认同步执行 (`async: false`)、阻塞等待返回值, 检查是否拒绝
|
|
99
|
-
|
|
100
|
-
<!-- 源码: src/hooks/hooks.ts reject 仅在 pre_tool_use 事件中断循环 -->
|
|
101
|
-
|
|
102
|
-
## 条件
|
|
103
|
-
|
|
104
|
-
<!-- 源码: src/hooks/hooks.ts evaluateSingleCondition -->
|
|
105
|
-
|
|
106
|
-
- == 等于, equal match
|
|
107
|
-
- != 不等于, not equal match
|
|
108
|
-
- =~ 正则匹配, regex match, 语法: `变量 =~ "正则表达式"`
|
|
109
|
-
- =\* glob (filesystem 通配符语法) 匹配, glob match
|
|
110
|
-
- 支持 && || 组合多个条件
|
|
111
|
-
|
|
112
|
-
变量名:
|
|
113
|
-
|
|
114
|
-
- tool: 匹配 ctx.toolName
|
|
115
|
-
- event: 匹配 ctx.event
|
|
116
|
-
- file_path 匹配 ctx.filePath
|
|
117
|
-
- message 匹配 ctx.message
|
|
118
|
-
- 其他变量名在工具参数字典 ctx.args 中按 key 查找, 例如 path 匹配 args.path, command 匹配 args.command
|
|
119
|
-
|
|
120
|
-
<!-- 源码: src/hooks/hooks.ts getContextValue -->
|
|
121
|
-
|
|
122
|
-
## 动作
|
|
123
|
-
|
|
124
|
-
<!-- 源码: src/hooks/hooks.ts executeAction -->
|
|
125
|
-
|
|
126
|
-
四种动作执行器
|
|
127
|
-
|
|
128
|
-
- command: 执行 shell 命令
|
|
129
|
-
- prompt: 注入 system prompt
|
|
130
|
-
- http: 发送 http 请求
|
|
131
|
-
- agent: 启动 subagent
|
|
132
|
-
|
|
133
|
-
### command
|
|
134
|
-
|
|
135
|
-
```yaml
|
|
136
|
-
action:
|
|
137
|
-
type: command
|
|
138
|
-
command: "prettier -w $SWIFTY_FILE_PATH"
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
<!-- 源码: src/hooks/hooks.ts executeAction command 分支 -->
|
|
142
|
-
|
|
143
|
-
- 执行 shell 命令, shell 命令执行前会设置环境变量 SWIFTY_EVENT, SWIFTY_TOOL, SWIFTY_FILE_PATH
|
|
144
|
-
- 启动一个 shell 子进程执行命令, 拿到输出和退出码
|
|
145
|
-
- timeout 字段指定命令超时时间
|
|
146
|
-
|
|
147
|
-
<!-- 源码: src/hooks/hooks.ts timeout 硬编码 30000ms, HookConfigSchema 没有 timeout 字段 -->
|
|
148
|
-
|
|
149
|
-
### prompt
|
|
150
|
-
|
|
151
|
-
<!-- 源码: src/hooks/hooks.ts executeAction prompt 分支 -->
|
|
152
|
-
|
|
153
|
-
```yaml
|
|
154
|
-
action:
|
|
155
|
-
type: prompt
|
|
156
|
-
prompt: 先阅读 ARCHITECTURE.md 了解项目架构, 再开始工作
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
- 使用 `<system-reminder />` 标签包裹, 作为一条 user 消息追加到对话历史, LLM 在下一轮 agent loop turn 请求中可以读到
|
|
160
|
-
- system prompt 不变、prompt cache 前缀不变
|
|
161
|
-
- 可以只在指定项目中注入, 或者只在第一轮对话中注入 (使用执行控制 `once: true`)
|
|
162
|
-
|
|
163
|
-
### http
|
|
164
|
-
|
|
165
|
-
<!-- 源码: src/hooks/hooks.ts executeAction http 分支 -->
|
|
166
|
-
|
|
167
|
-
```yaml
|
|
168
|
-
action:
|
|
169
|
-
type: http
|
|
170
|
-
url: https://api.example.com
|
|
171
|
-
method: POST
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
<!-- 源码: src/hooks/hooks.ts http 请求体固定为 JSON.stringify(context), HookConfigSchema 没有 body 字段 -->
|
|
175
|
-
|
|
176
|
-
发送 http 请求, 请求体是 HookContext 的 json 字符串 (包含 event, toolName, args, filePath, message 字段), 场景有: 发送 App 通知、日志收集、监控报警
|
|
177
|
-
|
|
178
|
-
### agent
|
|
179
|
-
|
|
180
|
-
```yaml
|
|
181
|
-
action:
|
|
182
|
-
type: agent
|
|
183
|
-
prompt: "review 刚刚写入的 $SWIFTY_FILE_PATH 是否有安全漏洞"
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
<!-- 源码: src/hooks/hooks.ts executeAction agent 分支 -->
|
|
187
|
-
|
|
188
|
-
启动 subagent, 见 ch13
|
|
189
|
-
|
|
190
|
-
## hook 执行控制
|
|
191
|
-
|
|
192
|
-
- once: 只执行一次
|
|
193
|
-
- async: 异步执行, 注意: pre_tool_use 事件的动作默认同步执行 (`async: false`)、阻塞等待返回值, 检查是否拒绝
|
|
194
|
-
- on_error: hook 执行错误时的行为, 枚举值:
|
|
195
|
-
- ignore: 默认, 忽略错误
|
|
196
|
-
- fail 标记 hook 执行错误
|
|
197
|
-
- reject 拒绝工具调用
|
|
198
|
-
- 错误捕获: hook 执行错误不能中断 Agent
|
|
199
|
-
|
|
200
|
-
<!-- 源码: src/hooks/hooks.ts on_error 处理逻辑 -->
|
|
201
|
-
|
|
202
|
-
```yaml
|
|
203
|
-
hooks:
|
|
204
|
-
- event: session_start
|
|
205
|
-
action:
|
|
206
|
-
type: prompt
|
|
207
|
-
prompt: "使用英文注释"
|
|
208
|
-
once: true
|
|
209
|
-
|
|
210
|
-
- event: post_tool_use
|
|
211
|
-
condition: tool == "WriteFile"
|
|
212
|
-
action:
|
|
213
|
-
type: http
|
|
214
|
-
url: https://api.example.com
|
|
215
|
-
method: POST
|
|
216
|
-
async: true
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
## 上下文变量
|
|
220
|
-
|
|
221
|
-
事件触发时, 创建一个 HookContext 对象, 包含事件的上下文信息:
|
|
222
|
-
|
|
223
|
-
<!-- 源码: src/hooks/hooks.ts HookContext 接口定义 -->
|
|
224
|
-
|
|
225
|
-
HookContext 属性:
|
|
226
|
-
|
|
227
|
-
- event 事件名 $SWIFTY_EVENT
|
|
228
|
-
- toolName 工具名 $SWIFTY_TOOL
|
|
229
|
-
- args 工具参数字典
|
|
230
|
-
- filePath 文件路径 $SWIFTY_FILE_PATH
|
|
231
|
-
- message 消息内容
|
|
232
|
-
|
|
233
|
-
<!-- 源码: src/hooks/hooks.ts 暴露 SWIFTY_EVENT, SWIFTY_TOOL, SWIFTY_FILE_PATH 环境变量 -->
|
|
234
|
-
|
|
235
|
-
## 示例配置
|
|
236
|
-
|
|
237
|
-
```yaml
|
|
238
|
-
hooks:
|
|
239
|
-
- id: auto-format
|
|
240
|
-
event: post_tool_use
|
|
241
|
-
condition: 'tool == "WriteFile" && path =* "*.ts"' # glob match
|
|
242
|
-
action:
|
|
243
|
-
type: command
|
|
244
|
-
command: "prettier -w $SWIFTY_FILE_PATH"
|
|
245
|
-
|
|
246
|
-
- id: readonly-vendor
|
|
247
|
-
event: pre_tool_use
|
|
248
|
-
condition: 'tool == "WriteFile" && path =* "node_modules/*"'
|
|
249
|
-
action:
|
|
250
|
-
type: command
|
|
251
|
-
command: "echo 'Never manually edit node_modules/*'"
|
|
252
|
-
reject: true
|
|
253
|
-
|
|
254
|
-
- id: project-context
|
|
255
|
-
event: session_start
|
|
256
|
-
action:
|
|
257
|
-
type: prompt
|
|
258
|
-
prompt: |
|
|
259
|
-
- Tech Stack: TypeScript, React, Ink, Zod, Vitest, ESLint, oxfmt, pnpm workspace deps: `@swifty.js/glob-addon`, `@swifty.js/glob-wasm`.
|
|
260
|
-
- Code Conventions: Enforced by `eslint.config.js`.
|
|
261
|
-
- Reference: Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
|
|
262
|
-
once: true
|
|
263
|
-
|
|
264
|
-
- id: block-dangerous-rm
|
|
265
|
-
event: pre_tool_use
|
|
266
|
-
condition: 'tool == "Bash" && command =~ "rm\\s+-rf\\s+\\/"'
|
|
267
|
-
action:
|
|
268
|
-
type: command
|
|
269
|
-
command: "echo 'Dangerous rm command detected'"
|
|
270
|
-
reject: true
|
|
271
|
-
|
|
272
|
-
- id: app-notify
|
|
273
|
-
event: post_tool_use
|
|
274
|
-
condition: 'tool == "WriteFile"'
|
|
275
|
-
action:
|
|
276
|
-
type: http
|
|
277
|
-
url: https://api.example.com
|
|
278
|
-
method: POST
|
|
279
|
-
async: true
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
## 配置校验
|
|
283
|
-
|
|
284
|
-
- reject 字段只能用于 pre_tool_use 事件
|
|
285
|
-
- async 字段不能用于 pre_tool_use 事件
|
|
286
|
-
- command 动作必须有 command 字段
|
|
287
|
-
- prompt 动作必须有 prompt 字段
|
|
288
|
-
- http 动作必须有 url 字段
|
|
289
|
-
- agent 动作必须有 prompt 字段或 command 字段
|