File watching service daemon that provides real-time notification of file and directory changes.
pkg:github/facebook/watchman@v2.0
npx @tessl/cli install tessl/github-watchman@2.0.00
# Watchman
1
2
A file watching service daemon that provides real-time notification of file and directory changes. Watchman monitors filesystem trees and executes actions when files change, enabling efficient file system monitoring for build systems, development tools, and other applications without the performance overhead of traditional polling approaches.
3
4
## Package Information
5
6
- **Package Name**: watchman
7
- **Language**: C
8
- **Installation**: Build from source (see installation instructions)
9
10
## Core Usage
11
12
### Command Line Interface
13
14
Watchman is provided as a single executable binary that acts as both the watchman service daemon and a client for that service.
15
16
```bash
17
# Start watching a directory
18
watchman watch ~/project
19
20
# List watched directories
21
watchman watch-list
22
23
# Query for changes since last check
24
watchman since ~/project n:mystate
25
26
# Find all files matching patterns
27
watchman find ~/project '*.js'
28
29
# Subscribe to file changes
30
watchman -j <<-EOT
31
["subscribe", "/path/to/root", "mysubscription", {
32
"expression": ["allof", ["type", "f"], ["suffix", "js"]],
33
"fields": ["name", "exists", "mtime"]
34
}]
35
EOT
36
```
37
38
### JSON Protocol
39
40
For programmatic access, Watchman uses a streaming JSON protocol over Unix domain sockets:
41
42
```bash
43
# Connect directly to socket
44
nc -U /tmp/.watchman.$USER
45
46
# Send JSON commands
47
["watch", "/path/to/directory"]
48
["since", "/path/to/directory", "n:mystate"]
49
```
50
51
## Architecture
52
53
Watchman operates as a long-lived service daemon with the following components:
54
55
- **Service Daemon**: Background process that monitors filesystem events using OS-specific APIs (inotify on Linux, kqueue on BSD/macOS, port_create on Solaris)
56
- **Client Interface**: Command-line tool and JSON protocol for communicating with the daemon
57
- **Watch Management**: Tracks filesystem trees and maintains file state databases
58
- **Query Engine**: Processes file queries with pattern matching and expression evaluation
59
- **Trigger System**: Executes commands automatically when files change
60
- **Subscription System**: Delivers real-time notifications of file changes
61
62
The daemon automatically spawns when first accessed and persists watches and triggers across restarts using a state file.
63
64
## Capabilities
65
66
### File Watching
67
68
Core filesystem monitoring operations for establishing watches, listing watched directories, and removing watches.
69
70
```bash { .api }
71
# Watch a directory tree
72
watchman watch <path>
73
74
# List all watched directories
75
watchman watch-list
76
77
# Stop watching a directory
78
watchman watch-del <path>
79
80
# Get current clock value for a watch
81
watchman clock <path>
82
```
83
84
[File Watching](./file-watching.md)
85
86
### Querying and Change Detection
87
88
Query the daemon for file information and changes, with support for time-based queries and pattern filtering.
89
90
```bash { .api }
91
# Find files matching patterns
92
watchman find <path> [patterns...]
93
94
# Query with expressions and field selection
95
watchman -j <<-EOT
96
["query", "/path", {
97
"expression": ["allof", ["type", "f"], ["suffix", "js"]],
98
"fields": ["name", "size", "mtime"]
99
}]
100
EOT
101
102
# Get changes since a specific time/clock
103
watchman since <path> <clockspec> [patterns...]
104
```
105
106
[Queries](./queries.md)
107
108
### Real-time Subscriptions
109
110
Subscribe to file change notifications that are delivered automatically as changes occur.
111
112
```bash { .api }
113
# Subscribe to changes
114
watchman -j <<-EOT
115
["subscribe", "/path", "subscription-name", {
116
"expression": ["suffix", "js"],
117
"fields": ["name", "exists"]
118
}]
119
EOT
120
121
# Cancel subscription
122
watchman unsubscribe <path> <subscription-name>
123
```
124
125
[Subscriptions](./subscriptions.md)
126
127
### Automated Triggers
128
129
Configure commands to execute automatically when files change, with pattern matching and batching support.
130
131
```bash { .api }
132
# Create trigger
133
watchman -- trigger <path> <trigger-name> [patterns...] -- <command> [args...]
134
135
# List triggers for a path
136
watchman trigger-list <path>
137
138
# Delete trigger
139
watchman trigger-del <path> <trigger-name>
140
```
141
142
[Triggers](./triggers.md)
143
144
### Command Line Options
145
146
Configuration options for the watchman binary:
147
148
```bash { .api }
149
# Socket and logging options
150
watchman -U <sockname> # Specify alternate socket path
151
watchman -o <logfile> # Specify log file path
152
watchman -f # Run in foreground
153
watchman -p # Persistent mode for multiple commands
154
155
# State management
156
watchman --statefile=<path> # Specify state file location
157
watchman -n # Don't save state between invocations
158
159
# JSON mode and formatting
160
watchman -j # Read JSON command from stdin
161
watchman --no-pretty # Don't pretty-print JSON output
162
watchman --no-spawn # Don't spawn daemon if not running
163
```
164
165
[CLI Options](./cli-options.md)
166
167
## Installation and Build
168
169
```bash { .api }
170
# Build from source
171
./autogen.sh
172
./configure
173
make
174
make install
175
```
176
177
[Installation](./installation.md)
178
179
## Core Types
180
181
### Clock Specifications
182
183
Time references used for change queries:
184
185
- **Unix timestamp**: `1234567890` (seconds since epoch)
186
- **Clock ID**: `c:123:456` (internal clock value)
187
- **Named cursor**: `n:mystate` (client-defined cursor name)
188
189
### JSON Response Format
190
191
Standard response structure for all commands:
192
193
```json
194
{
195
"version": "2.0",
196
"clock": "c:123:456",
197
"files": [...],
198
"root": "/path/to/watched/root"
199
}
200
```
201
202
### Expression System
203
204
Query expressions for filtering files:
205
206
- **Logical**: `["allof", expr1, expr2, ...]`, `["anyof", expr1, expr2, ...]`, `["not", expr]`
207
- **Pattern matching**: `["match", "*.js"]`, `["imatch", "*.JS"]` (case insensitive)
208
- **Name matching**: `["name", "Makefile"]`, `["name", ["file1", "file2"]]`
209
- **Type filtering**: `["type", "f"]` (f=file, d=directory, l=symlink, etc.)
210
- **Size/existence**: `["empty"]`, `["exists"]`
211
- **Time-based**: `["since", "c:123:456"]`, `["since", 1234567890, "mtime"]`
212
- **Regex**: `["pcre", "^test_"]`, `["ipcre", "test"]` (case insensitive)