or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-options.mdfile-watching.mdindex.mdinstallation.mdqueries.mdsubscriptions.mdtriggers.md

triggers.mddocs/

0

# Triggers and Automation

1

2

Configure commands to execute automatically when files change, with pattern matching and batching support. Triggers enable automated workflows based on file system changes.

3

4

## Capabilities

5

6

### Create Trigger

7

8

Set up a trigger that executes a command when files matching specified patterns change.

9

10

```bash { .api }

11

watchman -- trigger <path> <trigger-name> [patterns...] -- <command> [args...]

12

```

13

14

**JSON Protocol:**

15

```json

16

["trigger", "/absolute/path", "trigger-name", "pattern1", "pattern2", "--", "command", "arg1", "arg2"]

17

```

18

19

**Parameters:**

20

- `path`: Absolute path to watched directory (required)

21

- `trigger-name`: Unique name for this trigger (required)

22

- `patterns`: Filename patterns to match (optional)

23

- `command`: Command to execute (required)

24

- `args`: Command arguments (optional)

25

26

**Response:**

27

```json

28

{

29

"version": "2.0",

30

"triggerid": "unique-trigger-id"

31

}

32

```

33

34

The `--` separator is required when using the CLI to distinguish patterns from the command and its arguments.

35

36

**Example:**

37

```bash

38

# Trigger on JavaScript file changes

39

watchman -- trigger ~/project jsfiles '*.js' -- echo "JS file changed"

40

41

# Trigger with complex command

42

watchman -- trigger ~/project build '*.c' '*.h' -- make clean && make

43

44

# Trigger on any file change

45

watchman -- trigger ~/project notify -- notify-send "Files changed"

46

```

47

48

### List Triggers

49

50

Return all triggers registered for a watched directory.

51

52

```bash { .api }

53

watchman trigger-list <path>

54

```

55

56

**JSON Protocol:**

57

```json

58

["trigger-list", "/absolute/path"]

59

```

60

61

**Parameters:**

62

- `path`: Absolute path to watched directory (required)

63

64

**Response:**

65

```json

66

{

67

"version": "2.0",

68

"triggers": [

69

{

70

"name": "jsfiles",

71

"command": ["echo", "JS file changed"],

72

"expression": ["suffix", "js"],

73

"append_files": true

74

}

75

]

76

}

77

```

78

79

**Example:**

80

```bash

81

$ watchman trigger-list ~/project

82

{

83

"version": "2.0",

84

"triggers": [

85

{

86

"name": "build",

87

"command": ["make"],

88

"expression": ["anyof", ["suffix", "c"], ["suffix", "h"]]

89

}

90

]

91

}

92

```

93

94

### Delete Trigger

95

96

Remove a named trigger from a watched directory.

97

98

```bash { .api }

99

watchman trigger-del <path> <trigger-name>

100

```

101

102

**JSON Protocol:**

103

```json

104

["trigger-del", "/absolute/path", "trigger-name"]

105

```

106

107

**Parameters:**

108

- `path`: Absolute path to watched directory (required)

109

- `trigger-name`: Name of trigger to delete (required)

110

111

**Response:**

112

```json

113

{

114

"version": "2.0",

115

"deleted": true,

116

"trigger": "trigger-name"

117

}

118

```

119

120

**Example:**

121

```bash

122

# Delete a specific trigger

123

watchman trigger-del ~/project jsfiles

124

```

125

126

## Trigger Execution Behavior

127

128

### File System Settling

129

- Watchman waits for the filesystem to settle before executing triggers

130

- Default settle time is 20 milliseconds (configurable with `-s` option)

131

- Batches multiple file changes into a single trigger execution

132

133

### Command Execution

134

- Triggers execute in the watched directory (using `chdir`)

135

- Changed files are passed as command-line arguments

136

- Standard input receives JSON array of file information

137

- Only one instance of a trigger runs at a time per watch

138

139

### File Information Format

140

Standard input receives JSON with file details:

141

```json

142

[

143

{

144

"name": "src/main.js",

145

"exists": true,

146

"size": 1024,

147

"mode": 33188,

148

"mtime": 1234567890,

149

"new": false

150

}

151

]

152

```

153

154

### Command Line Length Limits

155

- Watchman respects system `ARG_MAX` limits

156

- If command line would be too long, excess files are truncated

157

- Use JSON input stream for processing large file lists

158

159

**Example reading JSON input:**

160

```bash

161

# Shell script that processes JSON input

162

#!/bin/bash

163

while read -r line; do

164

echo "Changed files: $line" | jq '.[] | .name'

165

done

166

```

167

168

## Advanced Trigger Configuration

169

170

### Pattern Matching

171

Triggers support the same pattern syntax as queries:

172

173

```bash

174

# Glob patterns

175

watchman -- trigger ~/project css '*.css' '*.scss' -- sass-compile

176

177

# Regex patterns

178

watchman -- trigger ~/project tests -p '\.test\.(js|ts)$' -- npm test

179

180

# Exclusion patterns

181

watchman -- trigger ~/project build '*.js' '! node_modules' -- webpack

182

```

183

184

### Trigger State Persistence

185

- Triggers are saved in the Watchman state file

186

- Automatically restored when Watchman restarts

187

- Use `--no-save-state` to disable persistence

188

189

### Environment Variables

190

Watchman provides environment variables to triggered commands:

191

- `WATCHMAN_ROOT`: The watched root path

192

- `WATCHMAN_SOCK`: Path to Watchman socket

193

- `WATCHMAN_TRIGGER`: Name of the trigger being executed

194

195

## Usage Examples

196

197

### Build System Integration

198

199

```bash

200

# Auto-compile on source changes

201

watchman -- trigger ~/project compile '*.c' '*.h' -- make

202

203

# Run tests when test files change

204

watchman -- trigger ~/project test '*.test.js' -- npm test

205

206

# Restart server on code changes

207

watchman -- trigger ~/project restart '*.js' '*.json' -- ./restart-server.sh

208

```

209

210

### Development Workflow

211

212

```bash

213

# Live reload for web development

214

watchman -- trigger ~/web static '*.html' '*.css' '*.js' -- browser-reload

215

216

# Generate documentation

217

watchman -- trigger ~/project docs '*.md' -- generate-docs

218

219

# Lint on file save

220

watchman -- trigger ~/project lint '*.js' -- eslint

221

```

222

223

### Custom Processing Script

224

225

```bash

226

#!/bin/bash

227

# process-changes.sh - Advanced trigger script

228

229

# Read JSON from stdin

230

changes=$(cat)

231

232

# Extract file names

233

files=$(echo "$changes" | jq -r '.[] | .name')

234

235

echo "Processing changes:"

236

for file in $files; do

237

echo " - $file"

238

239

# Custom processing based on file type

240

case "$file" in

241

*.js)

242

echo " Running JavaScript checks..."

243

eslint "$file"

244

;;

245

*.css)

246

echo " Processing CSS..."

247

autoprefixer "$file"

248

;;

249

*)

250

echo " No special processing"

251

;;

252

esac

253

done

254

```

255

256

Register the script as a trigger:

257

```bash

258

watchman -- trigger ~/project process '*.js' '*.css' -- ./process-changes.sh

259

```

260

261

## Error Handling and Debugging

262

263

### Trigger Execution Failures

264

- Failed commands don't prevent other triggers from running

265

- Check Watchman logs for execution errors

266

- Use `-f` flag to run Watchman in foreground for debugging

267

268

### Debugging Tips

269

- Use `watchman trigger-list` to verify trigger configuration

270

- Test commands manually before setting up triggers

271

- Check file permissions for trigger commands

272

- Monitor system resources if triggers execute frequently

273

274

### Common Issues

275

- **Command not found**: Ensure commands are in PATH or use absolute paths

276

- **Permission denied**: Verify execute permissions on trigger commands

277

- **Infinite loops**: Avoid triggers that modify files they watch

278

- **Resource exhaustion**: Limit trigger frequency for resource-intensive commands