Skill606 estrellas del repoactualizado today
watch
The watch skill automatically triggers actions when monitored file paths change or when marker comments like `@citadel:` appear in files. Use it to set up file sentinels that execute skills or commands in response to specific file modifications, rather than for one-off inspections or CI status monitoring on pull requests.
Instalar en Claude Code
Copiargit clone --depth 1 https://github.com/SethGammon/Citadel /tmp/watch && cp -r /tmp/watch/skills/watch ~/.claude/skills/watchDespués abre una sesión nueva de Claude Code; el skill carga automáticamente.
Definición
SKILL.md
# /watch -- File Sentinel
Use when the user wants automatic reactions to file changes or marker comments (`@citadel:`).
Do NOT use for one-off file inspection or tasks that need human judgment per file.
## Orientation
**Use when:** running a file sentinel that triggers a skill or command automatically when watched paths change.
**Don't use when:** monitoring CI status on a PR (use /pr-watch); running a one-shot verification check (use /verify).
## Default execution path (READ FIRST)
**`/watch start` does NOT call `CronCreate` by default.** Only pass `--remote`
to use Anthropic's routine system, and only after explicit user confirmation.
`CronCreate` counts against the **15 routine runs / 24h** cap — at the default
5-minute interval a watch exhausts the quota in under an hour.
### Default flow — `/watch start` (no `--remote` flag)
1. Do Steps 1 and 2 below (check existing watch, determine baseline commit).
2. **Skip Step 3** — do NOT call `CronCreate`. Leave `cronId: null` in state.
3. Write the state file (Step 4) with `status: "watching"`.
4. Output:
```
Watch state created: .planning/watch-state.json
Baseline: {commit hash, first 7 chars}
To start real-time watching, run in a separate terminal:
npm run watch:local
For cloud-persistent polling (machine off, user away):
/watch start --remote (uses CronCreate, counts against 15/day cap)
```
### Opt-in routine flow — `/watch start --remote`
Only when `--remote` is explicitly passed:
1. Confirm: "This will use `CronCreate`, which counts against your 15 routine
runs / 24h quota. At a 5-minute interval this exhausts the quota in under
an hour. Continue? (y/N)"
2. On confirmation, run the full Step 1–5 protocol including `CronCreate`.
## Commands
| Command | Behavior |
|---|---|
| `/watch start` | Default: create state, prompt user to run `npm run watch:local` |
| `/watch start --remote` | Use `CronCreate` polling (counts against 15/day quota — requires confirmation) |
| `/watch start --interval {N}m` | Set poll interval for `--remote` mode (default: 5m) |
| `/watch stop` | Stop watching, tear down cron |
| `/watch status` | Show watch state, last scan time, pending actions |
| `/watch scan` | Run a single scan now (manual trigger) |
## Protocol
### /watch start
#### Step 1: Check for existing watch
1. Read `.planning/watch-state.json` if it exists
2. If `status` is `"watching"`:
- Show current state: last scan time, interval, pending actions count
- Ask: "A watch is already active. Stop it and start a new one?"
- If yes: run `/watch stop` first, then continue
- If no: abort
#### Step 2: Determine baseline commit
1. Run `git rev-parse HEAD` to get the current commit hash
2. If not a git repo: fall back to timestamp-based detection (store current
time as `lastScanTime`, skip commit-based diffing)
3. Store this as `lastScanCommit`
#### Step 3: Create poll schedule (--remote only)
```
CronCreate:
interval: "{N}m" (default: 5m)
command: "/watch scan"
```
Save the cron ID in the state file.
#### Step 4: Write state file
Write `.planning/watch-state.json`:
```json
{
"status": "watching",
"lastScanCommit": "abc1234",
"lastScanTime": null,
"interval": "5m",
"cronId": "{id from step 3 or null}",
"pendingActions": {},
"processedMarkers": {},
"stats": {
"scansRun": 0,
"markersFound": 0,
"intakeItemsCreated": 0,
"skillsDispatched": 0
}
}
```
#### Step 5: Confirm (--remote only)
```
Watch started.
Interval: every {N}m
Baseline: {commit hash, first 7 chars}
State: .planning/watch-state.json
```
---
### /watch stop
1. Read `.planning/watch-state.json`. If missing or not `"watching"`: "No watch is active."
2. `CronDelete: {cronId}` — if cronId is missing or deletion fails, continue.
3. Update state: `"status": "stopped", "cronId": null`. Preserve all other fields.
4. Output:
```
Watch stopped.
Scans completed: {stats.scansRun}
Markers found: {stats.markersFound}
Intake items created: {stats.intakeItemsCreated}
Skills dispatched: {stats.skillsDispatched}
```
---
### /watch status
1. If `.planning/watch-state.json` missing: "No watch configured. Use `/watch start` to begin."
2. Output state fields: status, lastScanTime, lastScanCommit, interval, pendingActions.length, stats.
3. If `pendingActions` non-empty, list each: `[{action}] {file}:{line} -- {description}`
---
### /watch scan
#### Step 1: Load state
1. Read `.planning/watch-state.json`
2. If missing: create default state with `lastScanCommit` from `git rev-parse HEAD` and `status: "watching"`.
#### Step 2: Detect changed files
**Git mode (primary):**
1. `git diff --name-only {lastScanCommit} HEAD` (committed changes)
2. `git diff --name-only` (unstaged) and `git diff --name-only --cached` (staged)
3. Merge and deduplicate all three lists
**Fallback mode (no git):**
1. `find . -newer {timestamp_file} -type f`
2. Exclude `node_modules/`, `.git/`, `.planning/`, `dist/`, `build/`
If no files changed: update `lastScanTime` and `stats.scansRun`, exit early.
#### Step 3: Scan for marker comments
Search changed files for:
| Pattern | Languages |
|---|---|
| `// @citadel: {action} {description}` | JS, TS, Go, Rust, C, Java |
| `# @citadel: {action} {description}` | Python, Shell, YAML, Ruby |
| `/* @citadel: {action} {description} */` | CSS, multi-line C-style |
| `<!-- @citadel: {action} {description} -->` | HTML, Markdown |
**Action-to-skill mapping:**
| Action | Skill |
|---|---|
| `review` | `/review` |
| `test` | `/test-gen` |
| `fix` | `/systematic-debugging` |
| `document` | `/doc-gen` |
| `refactor` | `/refactor` |
| `todo` | intake item |
Unknown actions become intake items with the action preserved as metadata.
**Deduplication:** Every marker gets a stable identity hash: sha256 over `{file path}`, `{action}`, and the normalized marker text (trimmed, internal whitespace collapsed), joined with NUL separators and