@wonsukchoi/crondex 0.3.0 → 0.4.0
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 +19 -2
- package/catalog.json +265 -1
- package/jobs/content/rss-feed-validate.yaml +32 -0
- package/jobs/content/seo-meta-check.yaml +32 -0
- package/jobs/devops/api-rate-limit-check.yaml +31 -0
- package/jobs/devops/dns-record-check.yaml +32 -0
- package/jobs/devops/queue-depth-check.yaml +35 -0
- package/jobs/finance/invoice-overdue-check.yaml +32 -0
- package/jobs/finance/tax-deadline-reminder.yaml +33 -0
- package/jobs/security/firewall-rule-diff.yaml +30 -0
- package/jobs/security/sudo-usage-audit.yaml +35 -0
- package/jobs/team/1on1-prep-reminder.yaml +26 -0
- package/jobs/team/pto-balance-check.yaml +33 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -62,7 +62,8 @@ crondex/
|
|
|
62
62
|
│ ├── content/
|
|
63
63
|
│ ├── finance/
|
|
64
64
|
│ ├── security/
|
|
65
|
-
│
|
|
65
|
+
│ ├── learning/
|
|
66
|
+
│ └── team/
|
|
66
67
|
└── scripts/
|
|
67
68
|
├── build-catalog.js regenerates catalog.json from jobs/**/*.yaml
|
|
68
69
|
└── validate-jobs.js validates every job against the schema
|
|
@@ -70,7 +71,7 @@ crondex/
|
|
|
70
71
|
|
|
71
72
|
## Available jobs
|
|
72
73
|
|
|
73
|
-
|
|
74
|
+
46 jobs across 8 categories. Full details (description, tags, variables)
|
|
74
75
|
live in `catalog.json` and each job's YAML file — run `crondex list` or
|
|
75
76
|
browse `jobs/<category>/` for the plain-language rundown of each.
|
|
76
77
|
|
|
@@ -92,6 +93,9 @@ browse `jobs/<category>/` for the plain-language rundown of each.
|
|
|
92
93
|
| `db-backup-verify` | `0 5 * * *` | script |
|
|
93
94
|
| `license-compliance-check` | `0 8 * * 1` | script |
|
|
94
95
|
| `orphaned-branch-cleanup` | `0 9 * * 1` | script |
|
|
96
|
+
| `dns-record-check` | `0 */6 * * *` | script |
|
|
97
|
+
| `queue-depth-check` | `*/10 * * * *` | script |
|
|
98
|
+
| `api-rate-limit-check` | `*/15 * * * *` | script |
|
|
95
99
|
|
|
96
100
|
**productivity**
|
|
97
101
|
|
|
@@ -119,6 +123,8 @@ browse `jobs/<category>/` for the plain-language rundown of each.
|
|
|
119
123
|
| `changelog-digest` | `0 10 * * 5` | script + agent-prompt |
|
|
120
124
|
| `broken-link-check` | `0 7 * * 1` | script |
|
|
121
125
|
| `social-mentions-watch` | `0 9 * * *` | agent-prompt only |
|
|
126
|
+
| `seo-meta-check` | `0 7 * * 1` | script |
|
|
127
|
+
| `rss-feed-validate` | `0 8 * * *` | script |
|
|
122
128
|
|
|
123
129
|
**finance**
|
|
124
130
|
|
|
@@ -127,6 +133,8 @@ browse `jobs/<category>/` for the plain-language rundown of each.
|
|
|
127
133
|
| `subscription-audit` | `0 9 1 * *` | script |
|
|
128
134
|
| `net-worth-snapshot` | `0 9 1 * *` | script |
|
|
129
135
|
| `saas-seat-audit` | `0 9 1 * *` | script |
|
|
136
|
+
| `invoice-overdue-check` | `0 9 * * *` | script |
|
|
137
|
+
| `tax-deadline-reminder` | `0 9 * * *` | script |
|
|
130
138
|
|
|
131
139
|
**security**
|
|
132
140
|
|
|
@@ -135,6 +143,8 @@ browse `jobs/<category>/` for the plain-language rundown of each.
|
|
|
135
143
|
| `secrets-scan` | `0 3 * * *` | script |
|
|
136
144
|
| `open-port-check` | `0 */4 * * *` | script |
|
|
137
145
|
| `failed-login-watch` | `*/15 * * * *` | script |
|
|
146
|
+
| `sudo-usage-audit` | `0 * * * *` | script |
|
|
147
|
+
| `firewall-rule-diff` | `0 6 * * *` | script |
|
|
138
148
|
|
|
139
149
|
**learning**
|
|
140
150
|
|
|
@@ -144,6 +154,13 @@ browse `jobs/<category>/` for the plain-language rundown of each.
|
|
|
144
154
|
| `reading-list-nudge` | `0 9 * * 6` | script |
|
|
145
155
|
| `course-progress-checkin` | `0 9 * * 1` | script |
|
|
146
156
|
|
|
157
|
+
**team**
|
|
158
|
+
|
|
159
|
+
| id | schedule | modes |
|
|
160
|
+
|---|---|---|
|
|
161
|
+
| `1on1-prep-reminder` | `0 9 * * 3` | script |
|
|
162
|
+
| `pto-balance-check` | `0 9 1 * *` | script |
|
|
163
|
+
|
|
147
164
|
## How a job works
|
|
148
165
|
|
|
149
166
|
Every job is one YAML file with a `runner`:
|
package/catalog.json
CHANGED
|
@@ -1,8 +1,56 @@
|
|
|
1
1
|
{
|
|
2
2
|
"generated_by": "scripts/build-catalog.js",
|
|
3
3
|
"schema": "schema/job.schema.json",
|
|
4
|
-
"count":
|
|
4
|
+
"count": 46,
|
|
5
5
|
"jobs": [
|
|
6
|
+
{
|
|
7
|
+
"id": "1on1-prep-reminder",
|
|
8
|
+
"version": 1,
|
|
9
|
+
"name": "1:1 Prep Reminder",
|
|
10
|
+
"description": "Nudges you to prep talking points before a recurring 1:1 and shows your last notes. Use this if you've ever walked into a 1:1 with nothing prepared and just winged it.",
|
|
11
|
+
"category": "team",
|
|
12
|
+
"tags": [
|
|
13
|
+
"1on1",
|
|
14
|
+
"meetings",
|
|
15
|
+
"team"
|
|
16
|
+
],
|
|
17
|
+
"schedule": "0 9 * * 3",
|
|
18
|
+
"timezone": "America/Los_Angeles",
|
|
19
|
+
"runner": "shell",
|
|
20
|
+
"modes": [
|
|
21
|
+
"script"
|
|
22
|
+
],
|
|
23
|
+
"compatible_agents": [
|
|
24
|
+
"generic",
|
|
25
|
+
"claude",
|
|
26
|
+
"codex"
|
|
27
|
+
],
|
|
28
|
+
"path": "jobs/team/1on1-prep-reminder.yaml"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "api-rate-limit-check",
|
|
32
|
+
"version": 1,
|
|
33
|
+
"name": "API Rate Limit Check",
|
|
34
|
+
"description": "Checks how many API requests you have left before hitting a rate limit. Use this if you've ever gotten a 429 in production because nobody was watching the remaining quota.",
|
|
35
|
+
"category": "devops",
|
|
36
|
+
"tags": [
|
|
37
|
+
"api",
|
|
38
|
+
"rate-limit",
|
|
39
|
+
"monitoring"
|
|
40
|
+
],
|
|
41
|
+
"schedule": "*/15 * * * *",
|
|
42
|
+
"timezone": "UTC",
|
|
43
|
+
"runner": "shell",
|
|
44
|
+
"modes": [
|
|
45
|
+
"script"
|
|
46
|
+
],
|
|
47
|
+
"compatible_agents": [
|
|
48
|
+
"generic",
|
|
49
|
+
"claude",
|
|
50
|
+
"codex"
|
|
51
|
+
],
|
|
52
|
+
"path": "jobs/devops/api-rate-limit-check.yaml"
|
|
53
|
+
},
|
|
6
54
|
{
|
|
7
55
|
"id": "backup-reminder",
|
|
8
56
|
"version": 1,
|
|
@@ -279,6 +327,30 @@
|
|
|
279
327
|
],
|
|
280
328
|
"path": "jobs/devops/disk-space-check.yaml"
|
|
281
329
|
},
|
|
330
|
+
{
|
|
331
|
+
"id": "dns-record-check",
|
|
332
|
+
"version": 1,
|
|
333
|
+
"name": "DNS Record Drift Check",
|
|
334
|
+
"description": "Checks that a DNS record still resolves to the value you expect, and flags drift. Use this if you've ever had DNS quietly change (an expired record, a misconfigured provider) and only found out when something broke.",
|
|
335
|
+
"category": "devops",
|
|
336
|
+
"tags": [
|
|
337
|
+
"dns",
|
|
338
|
+
"monitoring",
|
|
339
|
+
"drift"
|
|
340
|
+
],
|
|
341
|
+
"schedule": "0 */6 * * *",
|
|
342
|
+
"timezone": "UTC",
|
|
343
|
+
"runner": "shell",
|
|
344
|
+
"modes": [
|
|
345
|
+
"script"
|
|
346
|
+
],
|
|
347
|
+
"compatible_agents": [
|
|
348
|
+
"generic",
|
|
349
|
+
"claude",
|
|
350
|
+
"codex"
|
|
351
|
+
],
|
|
352
|
+
"path": "jobs/devops/dns-record-check.yaml"
|
|
353
|
+
},
|
|
282
354
|
{
|
|
283
355
|
"id": "docker-image-prune",
|
|
284
356
|
"version": 1,
|
|
@@ -351,6 +423,30 @@
|
|
|
351
423
|
],
|
|
352
424
|
"path": "jobs/security/failed-login-watch.yaml"
|
|
353
425
|
},
|
|
426
|
+
{
|
|
427
|
+
"id": "firewall-rule-diff",
|
|
428
|
+
"version": 1,
|
|
429
|
+
"name": "Firewall Rule Diff",
|
|
430
|
+
"description": "Diffs your current firewall rules against a saved baseline and flags any drift. Use this if a firewall rule has ever changed without anyone remembering who did it or why.",
|
|
431
|
+
"category": "security",
|
|
432
|
+
"tags": [
|
|
433
|
+
"security",
|
|
434
|
+
"firewall",
|
|
435
|
+
"drift"
|
|
436
|
+
],
|
|
437
|
+
"schedule": "0 6 * * *",
|
|
438
|
+
"timezone": "UTC",
|
|
439
|
+
"runner": "shell",
|
|
440
|
+
"modes": [
|
|
441
|
+
"script"
|
|
442
|
+
],
|
|
443
|
+
"compatible_agents": [
|
|
444
|
+
"generic",
|
|
445
|
+
"claude",
|
|
446
|
+
"codex"
|
|
447
|
+
],
|
|
448
|
+
"path": "jobs/security/firewall-rule-diff.yaml"
|
|
449
|
+
},
|
|
354
450
|
{
|
|
355
451
|
"id": "focus-block-reminder",
|
|
356
452
|
"version": 1,
|
|
@@ -425,6 +521,30 @@
|
|
|
425
521
|
],
|
|
426
522
|
"path": "jobs/productivity/inbox-triage.yaml"
|
|
427
523
|
},
|
|
524
|
+
{
|
|
525
|
+
"id": "invoice-overdue-check",
|
|
526
|
+
"version": 1,
|
|
527
|
+
"name": "Invoice Overdue Check",
|
|
528
|
+
"description": "Flags invoices that are past due and still unpaid. Use this if you freelance or run a small business and invoices have ever slipped through the cracks.",
|
|
529
|
+
"category": "finance",
|
|
530
|
+
"tags": [
|
|
531
|
+
"invoices",
|
|
532
|
+
"accounts-receivable",
|
|
533
|
+
"finance"
|
|
534
|
+
],
|
|
535
|
+
"schedule": "0 9 * * *",
|
|
536
|
+
"timezone": "UTC",
|
|
537
|
+
"runner": "shell",
|
|
538
|
+
"modes": [
|
|
539
|
+
"script"
|
|
540
|
+
],
|
|
541
|
+
"compatible_agents": [
|
|
542
|
+
"generic",
|
|
543
|
+
"claude",
|
|
544
|
+
"codex"
|
|
545
|
+
],
|
|
546
|
+
"path": "jobs/finance/invoice-overdue-check.yaml"
|
|
547
|
+
},
|
|
428
548
|
{
|
|
429
549
|
"id": "license-compliance-check",
|
|
430
550
|
"version": 1,
|
|
@@ -571,6 +691,54 @@
|
|
|
571
691
|
],
|
|
572
692
|
"path": "jobs/devops/orphaned-branch-cleanup.yaml"
|
|
573
693
|
},
|
|
694
|
+
{
|
|
695
|
+
"id": "pto-balance-check",
|
|
696
|
+
"version": 1,
|
|
697
|
+
"name": "PTO Balance Check",
|
|
698
|
+
"description": "Warns you before unused PTO expires or resets. Use this if you've ever lost vacation days because you forgot they don't roll over.",
|
|
699
|
+
"category": "team",
|
|
700
|
+
"tags": [
|
|
701
|
+
"pto",
|
|
702
|
+
"vacation",
|
|
703
|
+
"team"
|
|
704
|
+
],
|
|
705
|
+
"schedule": "0 9 1 * *",
|
|
706
|
+
"timezone": "America/Los_Angeles",
|
|
707
|
+
"runner": "shell",
|
|
708
|
+
"modes": [
|
|
709
|
+
"script"
|
|
710
|
+
],
|
|
711
|
+
"compatible_agents": [
|
|
712
|
+
"generic",
|
|
713
|
+
"claude",
|
|
714
|
+
"codex"
|
|
715
|
+
],
|
|
716
|
+
"path": "jobs/team/pto-balance-check.yaml"
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
"id": "queue-depth-check",
|
|
720
|
+
"version": 1,
|
|
721
|
+
"name": "Queue Depth Check",
|
|
722
|
+
"description": "Checks how backed up a job queue is and warns if it crosses a threshold. Use this if a stuck worker has ever let a queue silently balloon until someone noticed customers weren't getting emails.",
|
|
723
|
+
"category": "devops",
|
|
724
|
+
"tags": [
|
|
725
|
+
"queue",
|
|
726
|
+
"redis",
|
|
727
|
+
"monitoring"
|
|
728
|
+
],
|
|
729
|
+
"schedule": "*/10 * * * *",
|
|
730
|
+
"timezone": "UTC",
|
|
731
|
+
"runner": "shell",
|
|
732
|
+
"modes": [
|
|
733
|
+
"script"
|
|
734
|
+
],
|
|
735
|
+
"compatible_agents": [
|
|
736
|
+
"generic",
|
|
737
|
+
"claude",
|
|
738
|
+
"codex"
|
|
739
|
+
],
|
|
740
|
+
"path": "jobs/devops/queue-depth-check.yaml"
|
|
741
|
+
},
|
|
574
742
|
{
|
|
575
743
|
"id": "reading-list-nudge",
|
|
576
744
|
"version": 1,
|
|
@@ -622,6 +790,30 @@
|
|
|
622
790
|
],
|
|
623
791
|
"path": "jobs/devops/repo-health-check.yaml"
|
|
624
792
|
},
|
|
793
|
+
{
|
|
794
|
+
"id": "rss-feed-validate",
|
|
795
|
+
"version": 1,
|
|
796
|
+
"name": "RSS Feed Validation",
|
|
797
|
+
"description": "Checks your RSS/Atom feed is valid XML and shows the most recent item's publish date. Use this if you've ever shipped a broken feed and only found out when a reader's app stopped updating.",
|
|
798
|
+
"category": "content",
|
|
799
|
+
"tags": [
|
|
800
|
+
"rss",
|
|
801
|
+
"feed",
|
|
802
|
+
"content"
|
|
803
|
+
],
|
|
804
|
+
"schedule": "0 8 * * *",
|
|
805
|
+
"timezone": "UTC",
|
|
806
|
+
"runner": "shell",
|
|
807
|
+
"modes": [
|
|
808
|
+
"script"
|
|
809
|
+
],
|
|
810
|
+
"compatible_agents": [
|
|
811
|
+
"generic",
|
|
812
|
+
"claude",
|
|
813
|
+
"codex"
|
|
814
|
+
],
|
|
815
|
+
"path": "jobs/content/rss-feed-validate.yaml"
|
|
816
|
+
},
|
|
625
817
|
{
|
|
626
818
|
"id": "saas-seat-audit",
|
|
627
819
|
"version": 1,
|
|
@@ -697,6 +889,30 @@
|
|
|
697
889
|
],
|
|
698
890
|
"path": "jobs/security/secrets-scan.yaml"
|
|
699
891
|
},
|
|
892
|
+
{
|
|
893
|
+
"id": "seo-meta-check",
|
|
894
|
+
"version": 1,
|
|
895
|
+
"name": "SEO Meta Tag Check",
|
|
896
|
+
"description": "Checks a list of pages for missing title, meta description, and Open Graph tags. Use this if pages have ever shipped without basic SEO/social-preview tags because nobody double-checked.",
|
|
897
|
+
"category": "content",
|
|
898
|
+
"tags": [
|
|
899
|
+
"seo",
|
|
900
|
+
"content",
|
|
901
|
+
"meta-tags"
|
|
902
|
+
],
|
|
903
|
+
"schedule": "0 7 * * 1",
|
|
904
|
+
"timezone": "UTC",
|
|
905
|
+
"runner": "shell",
|
|
906
|
+
"modes": [
|
|
907
|
+
"script"
|
|
908
|
+
],
|
|
909
|
+
"compatible_agents": [
|
|
910
|
+
"generic",
|
|
911
|
+
"claude",
|
|
912
|
+
"codex"
|
|
913
|
+
],
|
|
914
|
+
"path": "jobs/content/seo-meta-check.yaml"
|
|
915
|
+
},
|
|
700
916
|
{
|
|
701
917
|
"id": "social-mentions-watch",
|
|
702
918
|
"version": 1,
|
|
@@ -796,6 +1012,54 @@
|
|
|
796
1012
|
],
|
|
797
1013
|
"path": "jobs/finance/subscription-audit.yaml"
|
|
798
1014
|
},
|
|
1015
|
+
{
|
|
1016
|
+
"id": "sudo-usage-audit",
|
|
1017
|
+
"version": 1,
|
|
1018
|
+
"name": "Sudo Usage Audit",
|
|
1019
|
+
"description": "Reports new sudo commands run since the last check. Use this if you want to notice unexpected privilege escalation on a shared or internet-facing server.",
|
|
1020
|
+
"category": "security",
|
|
1021
|
+
"tags": [
|
|
1022
|
+
"security",
|
|
1023
|
+
"sudo",
|
|
1024
|
+
"audit"
|
|
1025
|
+
],
|
|
1026
|
+
"schedule": "0 * * * *",
|
|
1027
|
+
"timezone": "UTC",
|
|
1028
|
+
"runner": "shell",
|
|
1029
|
+
"modes": [
|
|
1030
|
+
"script"
|
|
1031
|
+
],
|
|
1032
|
+
"compatible_agents": [
|
|
1033
|
+
"generic",
|
|
1034
|
+
"claude",
|
|
1035
|
+
"codex"
|
|
1036
|
+
],
|
|
1037
|
+
"path": "jobs/security/sudo-usage-audit.yaml"
|
|
1038
|
+
},
|
|
1039
|
+
{
|
|
1040
|
+
"id": "tax-deadline-reminder",
|
|
1041
|
+
"version": 1,
|
|
1042
|
+
"name": "Tax Deadline Reminder",
|
|
1043
|
+
"description": "Warns you ahead of upcoming tax deadlines you've listed. Use this if quarterly estimated payments or annual filing dates have ever snuck up on you.",
|
|
1044
|
+
"category": "finance",
|
|
1045
|
+
"tags": [
|
|
1046
|
+
"tax",
|
|
1047
|
+
"deadlines",
|
|
1048
|
+
"finance"
|
|
1049
|
+
],
|
|
1050
|
+
"schedule": "0 9 * * *",
|
|
1051
|
+
"timezone": "UTC",
|
|
1052
|
+
"runner": "shell",
|
|
1053
|
+
"modes": [
|
|
1054
|
+
"script"
|
|
1055
|
+
],
|
|
1056
|
+
"compatible_agents": [
|
|
1057
|
+
"generic",
|
|
1058
|
+
"claude",
|
|
1059
|
+
"codex"
|
|
1060
|
+
],
|
|
1061
|
+
"path": "jobs/finance/tax-deadline-reminder.yaml"
|
|
1062
|
+
},
|
|
799
1063
|
{
|
|
800
1064
|
"id": "uptime-ping-check",
|
|
801
1065
|
"version": 1,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
id: rss-feed-validate
|
|
2
|
+
version: 1
|
|
3
|
+
name: RSS Feed Validation
|
|
4
|
+
description: >
|
|
5
|
+
Checks your RSS/Atom feed is valid XML and shows the most recent
|
|
6
|
+
item's publish date. Use this if you've ever shipped a broken feed
|
|
7
|
+
and only found out when a reader's app stopped updating.
|
|
8
|
+
category: content
|
|
9
|
+
tags: [rss, feed, content]
|
|
10
|
+
schedule: "0 8 * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
url={{feed_url}};
|
|
15
|
+
xml=$(curl -sL --max-time 10 "$url");
|
|
16
|
+
[ -z "$xml" ] && { echo "ERROR: could not fetch $url"; exit 1; };
|
|
17
|
+
if command -v xmllint >/dev/null 2>&1; then
|
|
18
|
+
echo "$xml" | xmllint --noout - 2>&1 && echo "OK: valid XML" || { echo "INVALID XML"; exit 1; };
|
|
19
|
+
else
|
|
20
|
+
echo "xmllint not installed, skipping strict XML validation";
|
|
21
|
+
fi;
|
|
22
|
+
pubdate=$(echo "$xml" | grep -oE "<pubDate>[^<]+</pubDate>" | head -n1 | sed 's/<[^>]*>//g');
|
|
23
|
+
echo "Most recent item pubDate: ${pubdate:-unknown}"
|
|
24
|
+
variables:
|
|
25
|
+
feed_url:
|
|
26
|
+
default: "https://example.com/feed.xml"
|
|
27
|
+
description: URL of the RSS/Atom feed to check.
|
|
28
|
+
compatible_agents: [generic, claude, codex]
|
|
29
|
+
notes: >
|
|
30
|
+
Zero-token. Only reports the latest pubDate for you to eyeball —
|
|
31
|
+
doesn't flag "stale" automatically since feed cadences vary too much
|
|
32
|
+
for one threshold. Install `xmllint` (libxml2) for strict validation.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
id: seo-meta-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: SEO Meta Tag Check
|
|
4
|
+
description: >
|
|
5
|
+
Checks a list of pages for missing title, meta description, and
|
|
6
|
+
Open Graph tags. Use this if pages have ever shipped without basic
|
|
7
|
+
SEO/social-preview tags because nobody double-checked.
|
|
8
|
+
category: content
|
|
9
|
+
tags: [seo, content, meta-tags]
|
|
10
|
+
schedule: "0 7 * * 1"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
file={{urls_file}};
|
|
15
|
+
[ -f "$file" ] || { echo "ERROR: $file not found"; exit 1; };
|
|
16
|
+
while IFS= read -r url; do
|
|
17
|
+
[ -z "$url" ] && continue;
|
|
18
|
+
html=$(curl -sL --max-time 10 "$url");
|
|
19
|
+
missing="";
|
|
20
|
+
echo "$html" | grep -qi "<title>" || missing="$missing title";
|
|
21
|
+
echo "$html" | grep -qi 'name="description"' || missing="$missing meta-description";
|
|
22
|
+
echo "$html" | grep -qi 'property="og:title"' || missing="$missing og:title";
|
|
23
|
+
if [ -n "$missing" ]; then echo "MISSING on $url:$missing"; else echo "OK: $url"; fi
|
|
24
|
+
done < "$file"
|
|
25
|
+
variables:
|
|
26
|
+
urls_file:
|
|
27
|
+
default: "./pages.txt"
|
|
28
|
+
description: Plain text file with one page URL per line to check.
|
|
29
|
+
compatible_agents: [generic, claude, codex]
|
|
30
|
+
notes: >
|
|
31
|
+
Zero-token. Basic presence check only (does the tag exist), not content
|
|
32
|
+
quality — pair with a fuller SEO audit for anything deeper.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
id: api-rate-limit-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: API Rate Limit Check
|
|
4
|
+
description: >
|
|
5
|
+
Checks how many API requests you have left before hitting a rate
|
|
6
|
+
limit. Use this if you've ever gotten a 429 in production because
|
|
7
|
+
nobody was watching the remaining quota.
|
|
8
|
+
category: devops
|
|
9
|
+
tags: [api, rate-limit, monitoring]
|
|
10
|
+
schedule: "*/15 * * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
url={{api_url}};
|
|
15
|
+
headers=$(curl -sI --max-time 10 "$url");
|
|
16
|
+
remaining=$(echo "$headers" | grep -i "^x-ratelimit-remaining:" | awk '{print $2}' | tr -d '\r');
|
|
17
|
+
if [ -z "$remaining" ]; then echo "no rate-limit headers found on $url (nothing to check, or a different header convention)"; exit 0;
|
|
18
|
+
elif [ "$remaining" -le {{warn_threshold}} ]; then echo "WARNING: $url has only $remaining requests remaining"; exit 1;
|
|
19
|
+
else echo "OK: $url has $remaining requests remaining"; fi
|
|
20
|
+
variables:
|
|
21
|
+
api_url:
|
|
22
|
+
default: "https://api.example.com/status"
|
|
23
|
+
description: An endpoint on the API you want to watch — any request that returns rate-limit headers works.
|
|
24
|
+
warn_threshold:
|
|
25
|
+
default: 50
|
|
26
|
+
description: Warn if remaining requests drops to this or below.
|
|
27
|
+
compatible_agents: [generic, claude, codex]
|
|
28
|
+
notes: >
|
|
29
|
+
Assumes the standard `X-RateLimit-Remaining` response header — adjust
|
|
30
|
+
the grep pattern if your API uses a different convention
|
|
31
|
+
(e.g. `RateLimit-Remaining`, a custom header).
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
id: dns-record-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: DNS Record Drift Check
|
|
4
|
+
description: >
|
|
5
|
+
Checks that a DNS record still resolves to the value you expect, and
|
|
6
|
+
flags drift. Use this if you've ever had DNS quietly change (an
|
|
7
|
+
expired record, a misconfigured provider) and only found out when
|
|
8
|
+
something broke.
|
|
9
|
+
category: devops
|
|
10
|
+
tags: [dns, monitoring, drift]
|
|
11
|
+
schedule: "0 */6 * * *"
|
|
12
|
+
timezone: "UTC"
|
|
13
|
+
runner: shell
|
|
14
|
+
command: >
|
|
15
|
+
domain={{domain}}; type={{record_type}}; expected="{{expected_value}}";
|
|
16
|
+
command -v dig >/dev/null 2>&1 || { echo "ERROR: dig not installed"; exit 1; };
|
|
17
|
+
actual=$(dig +short "$domain" "$type" | tr '\n' ' ' | sed 's/ *$//');
|
|
18
|
+
if [ -z "$actual" ]; then echo "ERROR: no $type record found for $domain"; exit 1;
|
|
19
|
+
elif echo "$actual" | grep -qF "$expected"; then echo "OK: $domain $type matches expected ($actual)";
|
|
20
|
+
else echo "DRIFT: $domain $type is '$actual', expected to contain '$expected'"; exit 1; fi
|
|
21
|
+
variables:
|
|
22
|
+
domain:
|
|
23
|
+
default: "example.com"
|
|
24
|
+
description: Domain to check.
|
|
25
|
+
record_type:
|
|
26
|
+
default: "A"
|
|
27
|
+
description: DNS record type (A, CNAME, TXT, MX, etc).
|
|
28
|
+
expected_value:
|
|
29
|
+
default: "93.184.216.34"
|
|
30
|
+
description: Value the record should contain — replace with your actual expected record.
|
|
31
|
+
compatible_agents: [generic, claude, codex]
|
|
32
|
+
notes: Zero-token, deterministic. Requires `dig` (part of dnsutils/bind-tools).
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
id: queue-depth-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: Queue Depth Check
|
|
4
|
+
description: >
|
|
5
|
+
Checks how backed up a job queue is and warns if it crosses a
|
|
6
|
+
threshold. Use this if a stuck worker has ever let a queue silently
|
|
7
|
+
balloon until someone noticed customers weren't getting emails.
|
|
8
|
+
category: devops
|
|
9
|
+
tags: [queue, redis, monitoring]
|
|
10
|
+
schedule: "*/10 * * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
command -v redis-cli >/dev/null 2>&1 || { echo "ERROR: redis-cli not installed"; exit 1; };
|
|
15
|
+
depth=$(redis-cli -h {{redis_host}} -p {{redis_port}} llen {{queue_key}} 2>/dev/null);
|
|
16
|
+
if [ -z "$depth" ]; then echo "ERROR: could not read queue depth for {{queue_key}}"; exit 1;
|
|
17
|
+
elif [ "$depth" -ge {{threshold}} ]; then echo "WARNING: queue {{queue_key}} depth is $depth (threshold {{threshold}})"; exit 1;
|
|
18
|
+
else echo "OK: queue {{queue_key}} depth is $depth"; fi
|
|
19
|
+
variables:
|
|
20
|
+
redis_host:
|
|
21
|
+
default: "localhost"
|
|
22
|
+
description: Redis host.
|
|
23
|
+
redis_port:
|
|
24
|
+
default: 6379
|
|
25
|
+
description: Redis port.
|
|
26
|
+
queue_key:
|
|
27
|
+
default: "jobs:pending"
|
|
28
|
+
description: Redis list key backing the queue.
|
|
29
|
+
threshold:
|
|
30
|
+
default: 1000
|
|
31
|
+
description: Warn if the queue depth reaches this many items.
|
|
32
|
+
compatible_agents: [generic, claude, codex]
|
|
33
|
+
notes: >
|
|
34
|
+
Redis list-backed queues only (uses LLEN). Adapt the depth-check
|
|
35
|
+
command for RabbitMQ, SQS, or other queue systems.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
id: invoice-overdue-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: Invoice Overdue Check
|
|
4
|
+
description: >
|
|
5
|
+
Flags invoices that are past due and still unpaid. Use this if you
|
|
6
|
+
freelance or run a small business and invoices have ever slipped
|
|
7
|
+
through the cracks.
|
|
8
|
+
category: finance
|
|
9
|
+
tags: [invoices, accounts-receivable, finance]
|
|
10
|
+
schedule: "0 9 * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
file={{invoices_file}};
|
|
15
|
+
[ -f "$file" ] || { echo "ERROR: $file not found"; exit 1; };
|
|
16
|
+
today=$(date +%s);
|
|
17
|
+
tail -n +2 "$file" | while IFS=, read -r id client amount due paid; do
|
|
18
|
+
[ "$paid" = "yes" ] && continue;
|
|
19
|
+
due_epoch=$(date -j -f %Y-%m-%d "$due" +%s 2>/dev/null || date -d "$due" +%s);
|
|
20
|
+
days=$(( (today-due_epoch)/86400 ));
|
|
21
|
+
if [ "$days" -gt 0 ]; then echo "OVERDUE: invoice $id ($client, \$$amount) — $days day(s) past due ($due)"; fi
|
|
22
|
+
done
|
|
23
|
+
variables:
|
|
24
|
+
invoices_file:
|
|
25
|
+
default: "./invoices.csv"
|
|
26
|
+
description: >
|
|
27
|
+
CSV with header "invoice_id,client,amount,due_date,paid"
|
|
28
|
+
(due_date is YYYY-MM-DD, paid is yes/no).
|
|
29
|
+
compatible_agents: [generic, claude, codex]
|
|
30
|
+
notes: >
|
|
31
|
+
Zero-token. You maintain invoices.csv yourself (mark paid=yes once
|
|
32
|
+
settled) — this doesn't connect to any billing/accounting system.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
id: tax-deadline-reminder
|
|
2
|
+
version: 1
|
|
3
|
+
name: Tax Deadline Reminder
|
|
4
|
+
description: >
|
|
5
|
+
Warns you ahead of upcoming tax deadlines you've listed. Use this if
|
|
6
|
+
quarterly estimated payments or annual filing dates have ever snuck
|
|
7
|
+
up on you.
|
|
8
|
+
category: finance
|
|
9
|
+
tags: [tax, deadlines, finance]
|
|
10
|
+
schedule: "0 9 * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
file={{deadlines_file}}; warn={{warn_days}};
|
|
15
|
+
[ -f "$file" ] || { echo "ERROR: $file not found"; exit 1; };
|
|
16
|
+
today=$(date +%s);
|
|
17
|
+
tail -n +2 "$file" | while IFS=, read -r label due; do
|
|
18
|
+
[ -z "$due" ] && continue;
|
|
19
|
+
due_epoch=$(date -j -f %Y-%m-%d "$due" +%s 2>/dev/null || date -d "$due" +%s);
|
|
20
|
+
days=$(( (due_epoch-today)/86400 ));
|
|
21
|
+
if [ "$days" -ge 0 ] && [ "$days" -le "$warn" ]; then echo "REMINDER: $label due in $days day(s) ($due)"; fi
|
|
22
|
+
done
|
|
23
|
+
variables:
|
|
24
|
+
deadlines_file:
|
|
25
|
+
default: "./tax-deadlines.csv"
|
|
26
|
+
description: CSV with header "label,date" (date is YYYY-MM-DD), one deadline per row.
|
|
27
|
+
warn_days:
|
|
28
|
+
default: 14
|
|
29
|
+
description: Start warning this many days before a deadline.
|
|
30
|
+
compatible_agents: [generic, claude, codex]
|
|
31
|
+
notes: >
|
|
32
|
+
Zero-token. You maintain tax-deadlines.csv yourself with your actual
|
|
33
|
+
jurisdiction's dates — this job doesn't know tax law or deadlines on its own.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
id: firewall-rule-diff
|
|
2
|
+
version: 1
|
|
3
|
+
name: Firewall Rule Diff
|
|
4
|
+
description: >
|
|
5
|
+
Diffs your current firewall rules against a saved baseline and flags
|
|
6
|
+
any drift. Use this if a firewall rule has ever changed without
|
|
7
|
+
anyone remembering who did it or why.
|
|
8
|
+
category: security
|
|
9
|
+
tags: [security, firewall, drift]
|
|
10
|
+
schedule: "0 6 * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
baseline={{baseline_path}};
|
|
15
|
+
if command -v ufw >/dev/null 2>&1; then current=$(sudo ufw status verbose 2>/dev/null);
|
|
16
|
+
elif command -v iptables >/dev/null 2>&1; then current=$(sudo iptables -S 2>/dev/null);
|
|
17
|
+
else echo "ERROR: no supported firewall tool found (ufw/iptables)"; exit 1; fi;
|
|
18
|
+
if [ ! -f "$baseline" ]; then echo "$current" > "$baseline"; echo "no baseline found — saved current rules as the new baseline"; exit 0; fi;
|
|
19
|
+
if diff -q <(echo "$current") "$baseline" >/dev/null 2>&1; then echo "OK: firewall rules match baseline";
|
|
20
|
+
else echo "DRIFT: firewall rules differ from baseline:"; diff <(echo "$current") "$baseline"; exit 1; fi
|
|
21
|
+
variables:
|
|
22
|
+
baseline_path:
|
|
23
|
+
default: "./firewall-baseline.txt"
|
|
24
|
+
description: File storing the known-good firewall rule snapshot.
|
|
25
|
+
compatible_agents: [generic, claude, codex]
|
|
26
|
+
notes: >
|
|
27
|
+
Requires sudo access to read ufw/iptables rules (configure passwordless
|
|
28
|
+
sudo for this specific read-only command if running unattended). First
|
|
29
|
+
run saves the baseline; later runs diff against it. Requires bash
|
|
30
|
+
(process substitution).
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
id: sudo-usage-audit
|
|
2
|
+
version: 1
|
|
3
|
+
name: Sudo Usage Audit
|
|
4
|
+
description: >
|
|
5
|
+
Reports new sudo commands run since the last check. Use this if you
|
|
6
|
+
want to notice unexpected privilege escalation on a shared or
|
|
7
|
+
internet-facing server.
|
|
8
|
+
category: security
|
|
9
|
+
tags: [security, sudo, audit]
|
|
10
|
+
schedule: "0 * * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
log={{auth_log_path}}; state={{state_file}};
|
|
15
|
+
[ -f "$log" ] || { echo "ERROR: $log not found"; exit 1; };
|
|
16
|
+
total=$(grep -c "sudo:.*COMMAND=" "$log");
|
|
17
|
+
last=$(cat "$state" 2>/dev/null || echo 0);
|
|
18
|
+
new=$(( total - last ));
|
|
19
|
+
[ "$new" -lt 0 ] && new=0;
|
|
20
|
+
echo "$total" > "$state";
|
|
21
|
+
if [ "$new" -gt 0 ]; then
|
|
22
|
+
echo "New sudo commands since last check ($new):";
|
|
23
|
+
grep "sudo:.*COMMAND=" "$log" | tail -n "$new";
|
|
24
|
+
else echo "OK: no new sudo usage since last check"; fi
|
|
25
|
+
variables:
|
|
26
|
+
auth_log_path:
|
|
27
|
+
default: "/var/log/auth.log"
|
|
28
|
+
description: Path to the auth log (Linux-style).
|
|
29
|
+
state_file:
|
|
30
|
+
default: "./.sudo-audit-state"
|
|
31
|
+
description: File this job uses to remember the last count seen, so it only reports new entries.
|
|
32
|
+
compatible_agents: [generic, claude, codex]
|
|
33
|
+
notes: >
|
|
34
|
+
Linux-oriented (/var/log/auth.log with sudo entries). On macOS use
|
|
35
|
+
`log show --predicate 'process == "sudo"'` instead and adapt the command.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
id: 1on1-prep-reminder
|
|
2
|
+
version: 1
|
|
3
|
+
name: 1:1 Prep Reminder
|
|
4
|
+
description: >
|
|
5
|
+
Nudges you to prep talking points before a recurring 1:1 and shows
|
|
6
|
+
your last notes. Use this if you've ever walked into a 1:1 with
|
|
7
|
+
nothing prepared and just winged it.
|
|
8
|
+
category: team
|
|
9
|
+
tags: [1on1, meetings, team]
|
|
10
|
+
schedule: "0 9 * * 3"
|
|
11
|
+
timezone: "America/Los_Angeles"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
echo "1:1 with {{person_name}} coming up. Jot down talking points.";
|
|
15
|
+
if [ -f "{{notes_file}}" ]; then echo "--- last notes ---"; tail -n 10 "{{notes_file}}"; fi
|
|
16
|
+
variables:
|
|
17
|
+
person_name:
|
|
18
|
+
default: "your manager"
|
|
19
|
+
description: Who the 1:1 is with.
|
|
20
|
+
notes_file:
|
|
21
|
+
default: "./1on1-notes.txt"
|
|
22
|
+
description: Plain text file you append notes/action items to after each 1:1.
|
|
23
|
+
compatible_agents: [generic, claude, codex]
|
|
24
|
+
notes: >
|
|
25
|
+
Zero-token. Adjust the schedule to match your actual 1:1 day/time —
|
|
26
|
+
the default (Wednesday morning) is just a placeholder.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
id: pto-balance-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: PTO Balance Check
|
|
4
|
+
description: >
|
|
5
|
+
Warns you before unused PTO expires or resets. Use this if you've
|
|
6
|
+
ever lost vacation days because you forgot they don't roll over.
|
|
7
|
+
category: team
|
|
8
|
+
tags: [pto, vacation, team]
|
|
9
|
+
schedule: "0 9 1 * *"
|
|
10
|
+
timezone: "America/Los_Angeles"
|
|
11
|
+
runner: shell
|
|
12
|
+
command: >
|
|
13
|
+
today_epoch=$(date +%s);
|
|
14
|
+
expiry_epoch=$(date -j -f %Y-%m-%d "{{expiry_date}}" +%s 2>/dev/null || date -d "{{expiry_date}}" +%s);
|
|
15
|
+
days_left=$(( (expiry_epoch-today_epoch)/86400 ));
|
|
16
|
+
if [ "$days_left" -lt 0 ]; then echo "note: expiry date has passed — update expiry_date for the next period.";
|
|
17
|
+
elif [ "$days_left" -le {{warn_days_before_expiry}} ] && [ {{pto_balance_hours}} -gt 0 ]; then
|
|
18
|
+
echo "REMINDER: {{pto_balance_hours}}h PTO expires in $days_left day(s) (on {{expiry_date}}) — use it or lose it.";
|
|
19
|
+
else echo "OK: {{pto_balance_hours}}h PTO, $days_left day(s) until expiry."; fi
|
|
20
|
+
variables:
|
|
21
|
+
pto_balance_hours:
|
|
22
|
+
default: 40
|
|
23
|
+
description: Your current unused PTO balance, in hours — update this yourself as it changes.
|
|
24
|
+
expiry_date:
|
|
25
|
+
default: "2026-12-31"
|
|
26
|
+
description: Date (YYYY-MM-DD) this PTO expires or resets.
|
|
27
|
+
warn_days_before_expiry:
|
|
28
|
+
default: 30
|
|
29
|
+
description: Start warning this many days before expiry.
|
|
30
|
+
compatible_agents: [generic, claude, codex]
|
|
31
|
+
notes: >
|
|
32
|
+
Zero-token. You maintain pto_balance_hours and expiry_date yourself —
|
|
33
|
+
this doesn't pull from any HR system.
|