@wonsukchoi/crondex 0.4.0 → 0.5.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 +30 -2
- package/catalog.json +244 -1
- package/jobs/content/robots-txt-check.yaml +30 -0
- package/jobs/growth/cart-abandonment-followup.yaml +46 -0
- package/jobs/growth/review-request-nudge.yaml +35 -0
- package/jobs/home/hvac-filter-reminder.yaml +29 -0
- package/jobs/home/plant-watering-reminder.yaml +30 -0
- package/jobs/home/smoke-detector-battery-check.yaml +29 -0
- package/jobs/security/certificate-transparency-watch.yaml +31 -0
- package/jobs/travel/flight-checkin-reminder.yaml +31 -0
- package/jobs/travel/passport-expiry-check.yaml +31 -0
- package/jobs/travel/visa-expiry-check.yaml +32 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -63,7 +63,10 @@ crondex/
|
|
|
63
63
|
│ ├── finance/
|
|
64
64
|
│ ├── security/
|
|
65
65
|
│ ├── learning/
|
|
66
|
-
│
|
|
66
|
+
│ ├── team/
|
|
67
|
+
│ ├── home/
|
|
68
|
+
│ ├── travel/
|
|
69
|
+
│ └── growth/
|
|
67
70
|
└── scripts/
|
|
68
71
|
├── build-catalog.js regenerates catalog.json from jobs/**/*.yaml
|
|
69
72
|
└── validate-jobs.js validates every job against the schema
|
|
@@ -71,7 +74,7 @@ crondex/
|
|
|
71
74
|
|
|
72
75
|
## Available jobs
|
|
73
76
|
|
|
74
|
-
|
|
77
|
+
56 jobs across 11 categories. Full details (description, tags, variables)
|
|
75
78
|
live in `catalog.json` and each job's YAML file — run `crondex list` or
|
|
76
79
|
browse `jobs/<category>/` for the plain-language rundown of each.
|
|
77
80
|
|
|
@@ -125,6 +128,7 @@ browse `jobs/<category>/` for the plain-language rundown of each.
|
|
|
125
128
|
| `social-mentions-watch` | `0 9 * * *` | agent-prompt only |
|
|
126
129
|
| `seo-meta-check` | `0 7 * * 1` | script |
|
|
127
130
|
| `rss-feed-validate` | `0 8 * * *` | script |
|
|
131
|
+
| `robots-txt-check` | `0 8 * * *` | script |
|
|
128
132
|
|
|
129
133
|
**finance**
|
|
130
134
|
|
|
@@ -145,6 +149,7 @@ browse `jobs/<category>/` for the plain-language rundown of each.
|
|
|
145
149
|
| `failed-login-watch` | `*/15 * * * *` | script |
|
|
146
150
|
| `sudo-usage-audit` | `0 * * * *` | script |
|
|
147
151
|
| `firewall-rule-diff` | `0 6 * * *` | script |
|
|
152
|
+
| `certificate-transparency-watch` | `0 */12 * * *` | script |
|
|
148
153
|
|
|
149
154
|
**learning**
|
|
150
155
|
|
|
@@ -161,6 +166,29 @@ browse `jobs/<category>/` for the plain-language rundown of each.
|
|
|
161
166
|
| `1on1-prep-reminder` | `0 9 * * 3` | script |
|
|
162
167
|
| `pto-balance-check` | `0 9 1 * *` | script |
|
|
163
168
|
|
|
169
|
+
**home**
|
|
170
|
+
|
|
171
|
+
| id | schedule | modes |
|
|
172
|
+
|---|---|---|
|
|
173
|
+
| `hvac-filter-reminder` | `0 9 1 * *` | script |
|
|
174
|
+
| `smoke-detector-battery-check` | `0 9 1 * *` | script |
|
|
175
|
+
| `plant-watering-reminder` | `0 9 * * *` | script |
|
|
176
|
+
|
|
177
|
+
**travel**
|
|
178
|
+
|
|
179
|
+
| id | schedule | modes |
|
|
180
|
+
|---|---|---|
|
|
181
|
+
| `passport-expiry-check` | `0 9 1 * *` | script |
|
|
182
|
+
| `visa-expiry-check` | `0 9 1 * *` | script |
|
|
183
|
+
| `flight-checkin-reminder` | `0 * * * *` | script |
|
|
184
|
+
|
|
185
|
+
**growth**
|
|
186
|
+
|
|
187
|
+
| id | schedule | modes |
|
|
188
|
+
|---|---|---|
|
|
189
|
+
| `review-request-nudge` | `0 9 * * *` | script |
|
|
190
|
+
| `cart-abandonment-followup` | `0 10 * * *` | script + agent-prompt |
|
|
191
|
+
|
|
164
192
|
## How a job works
|
|
165
193
|
|
|
166
194
|
Every job is one YAML file with a `runner`:
|
package/catalog.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"generated_by": "scripts/build-catalog.js",
|
|
3
3
|
"schema": "schema/job.schema.json",
|
|
4
|
-
"count":
|
|
4
|
+
"count": 56,
|
|
5
5
|
"jobs": [
|
|
6
6
|
{
|
|
7
7
|
"id": "1on1-prep-reminder",
|
|
@@ -123,6 +123,57 @@
|
|
|
123
123
|
],
|
|
124
124
|
"path": "jobs/content/broken-link-check.yaml"
|
|
125
125
|
},
|
|
126
|
+
{
|
|
127
|
+
"id": "cart-abandonment-followup",
|
|
128
|
+
"version": 1,
|
|
129
|
+
"name": "Cart Abandonment Follow-up",
|
|
130
|
+
"description": "Finds abandoned shopping carts old enough to follow up on, and can draft the follow-up email for you. Use this if abandoned-cart recovery is something you know you should do but never get to.",
|
|
131
|
+
"category": "growth",
|
|
132
|
+
"tags": [
|
|
133
|
+
"growth",
|
|
134
|
+
"ecommerce",
|
|
135
|
+
"cart-recovery"
|
|
136
|
+
],
|
|
137
|
+
"schedule": "0 10 * * *",
|
|
138
|
+
"timezone": "UTC",
|
|
139
|
+
"runner": "hybrid",
|
|
140
|
+
"modes": [
|
|
141
|
+
"script",
|
|
142
|
+
"agent-prompt"
|
|
143
|
+
],
|
|
144
|
+
"compatible_agents": [
|
|
145
|
+
"claude",
|
|
146
|
+
"codex",
|
|
147
|
+
"hermes",
|
|
148
|
+
"openclaw",
|
|
149
|
+
"generic"
|
|
150
|
+
],
|
|
151
|
+
"path": "jobs/growth/cart-abandonment-followup.yaml"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"id": "certificate-transparency-watch",
|
|
155
|
+
"version": 1,
|
|
156
|
+
"name": "Certificate Transparency Watch",
|
|
157
|
+
"description": "Checks public Certificate Transparency logs for new TLS certs issued for your domain and flags any you didn't expect. Use this if you want an early warning for someone issuing a cert for your domain without your knowledge (a common precursor to phishing/MITM setups).",
|
|
158
|
+
"category": "security",
|
|
159
|
+
"tags": [
|
|
160
|
+
"security",
|
|
161
|
+
"tls",
|
|
162
|
+
"certificate-transparency"
|
|
163
|
+
],
|
|
164
|
+
"schedule": "0 */12 * * *",
|
|
165
|
+
"timezone": "UTC",
|
|
166
|
+
"runner": "shell",
|
|
167
|
+
"modes": [
|
|
168
|
+
"script"
|
|
169
|
+
],
|
|
170
|
+
"compatible_agents": [
|
|
171
|
+
"generic",
|
|
172
|
+
"claude",
|
|
173
|
+
"codex"
|
|
174
|
+
],
|
|
175
|
+
"path": "jobs/security/certificate-transparency-watch.yaml"
|
|
176
|
+
},
|
|
126
177
|
{
|
|
127
178
|
"id": "changelog-digest",
|
|
128
179
|
"version": 1,
|
|
@@ -447,6 +498,30 @@
|
|
|
447
498
|
],
|
|
448
499
|
"path": "jobs/security/firewall-rule-diff.yaml"
|
|
449
500
|
},
|
|
501
|
+
{
|
|
502
|
+
"id": "flight-checkin-reminder",
|
|
503
|
+
"version": 1,
|
|
504
|
+
"name": "Flight Check-in Reminder",
|
|
505
|
+
"description": "Reminds you when online check-in opens for an upcoming flight. Use this if you've ever missed the good seats because check-in opened while you were asleep.",
|
|
506
|
+
"category": "travel",
|
|
507
|
+
"tags": [
|
|
508
|
+
"travel",
|
|
509
|
+
"flight",
|
|
510
|
+
"reminder"
|
|
511
|
+
],
|
|
512
|
+
"schedule": "0 * * * *",
|
|
513
|
+
"timezone": "UTC",
|
|
514
|
+
"runner": "shell",
|
|
515
|
+
"modes": [
|
|
516
|
+
"script"
|
|
517
|
+
],
|
|
518
|
+
"compatible_agents": [
|
|
519
|
+
"generic",
|
|
520
|
+
"claude",
|
|
521
|
+
"codex"
|
|
522
|
+
],
|
|
523
|
+
"path": "jobs/travel/flight-checkin-reminder.yaml"
|
|
524
|
+
},
|
|
450
525
|
{
|
|
451
526
|
"id": "focus-block-reminder",
|
|
452
527
|
"version": 1,
|
|
@@ -495,6 +570,30 @@
|
|
|
495
570
|
],
|
|
496
571
|
"path": "jobs/personal/habit-checkin.yaml"
|
|
497
572
|
},
|
|
573
|
+
{
|
|
574
|
+
"id": "hvac-filter-reminder",
|
|
575
|
+
"version": 1,
|
|
576
|
+
"name": "HVAC Filter Change Reminder",
|
|
577
|
+
"description": "Reminds you to change your HVAC filter based on how long it's been. Use this if you've ever found a filter so clogged you forgot it was ever white.",
|
|
578
|
+
"category": "home",
|
|
579
|
+
"tags": [
|
|
580
|
+
"home",
|
|
581
|
+
"hvac",
|
|
582
|
+
"maintenance"
|
|
583
|
+
],
|
|
584
|
+
"schedule": "0 9 1 * *",
|
|
585
|
+
"timezone": "America/Los_Angeles",
|
|
586
|
+
"runner": "shell",
|
|
587
|
+
"modes": [
|
|
588
|
+
"script"
|
|
589
|
+
],
|
|
590
|
+
"compatible_agents": [
|
|
591
|
+
"generic",
|
|
592
|
+
"claude",
|
|
593
|
+
"codex"
|
|
594
|
+
],
|
|
595
|
+
"path": "jobs/home/hvac-filter-reminder.yaml"
|
|
596
|
+
},
|
|
498
597
|
{
|
|
499
598
|
"id": "inbox-triage",
|
|
500
599
|
"version": 1,
|
|
@@ -691,6 +790,54 @@
|
|
|
691
790
|
],
|
|
692
791
|
"path": "jobs/devops/orphaned-branch-cleanup.yaml"
|
|
693
792
|
},
|
|
793
|
+
{
|
|
794
|
+
"id": "passport-expiry-check",
|
|
795
|
+
"version": 1,
|
|
796
|
+
"name": "Passport Expiry Check",
|
|
797
|
+
"description": "Warns you before your passport expires — including the \"6 months validity required\" rule many countries enforce at the border. Use this if you've ever booked a trip and only checked your passport date after buying the ticket.",
|
|
798
|
+
"category": "travel",
|
|
799
|
+
"tags": [
|
|
800
|
+
"travel",
|
|
801
|
+
"passport",
|
|
802
|
+
"documents"
|
|
803
|
+
],
|
|
804
|
+
"schedule": "0 9 1 * *",
|
|
805
|
+
"timezone": "UTC",
|
|
806
|
+
"runner": "shell",
|
|
807
|
+
"modes": [
|
|
808
|
+
"script"
|
|
809
|
+
],
|
|
810
|
+
"compatible_agents": [
|
|
811
|
+
"generic",
|
|
812
|
+
"claude",
|
|
813
|
+
"codex"
|
|
814
|
+
],
|
|
815
|
+
"path": "jobs/travel/passport-expiry-check.yaml"
|
|
816
|
+
},
|
|
817
|
+
{
|
|
818
|
+
"id": "plant-watering-reminder",
|
|
819
|
+
"version": 1,
|
|
820
|
+
"name": "Plant Watering Reminder",
|
|
821
|
+
"description": "Reminds you to water a specific plant once it's due. Use this if you've ever lost a plant to \"I'll water it tomorrow.\"",
|
|
822
|
+
"category": "home",
|
|
823
|
+
"tags": [
|
|
824
|
+
"home",
|
|
825
|
+
"plants",
|
|
826
|
+
"reminder"
|
|
827
|
+
],
|
|
828
|
+
"schedule": "0 9 * * *",
|
|
829
|
+
"timezone": "America/Los_Angeles",
|
|
830
|
+
"runner": "shell",
|
|
831
|
+
"modes": [
|
|
832
|
+
"script"
|
|
833
|
+
],
|
|
834
|
+
"compatible_agents": [
|
|
835
|
+
"generic",
|
|
836
|
+
"claude",
|
|
837
|
+
"codex"
|
|
838
|
+
],
|
|
839
|
+
"path": "jobs/home/plant-watering-reminder.yaml"
|
|
840
|
+
},
|
|
694
841
|
{
|
|
695
842
|
"id": "pto-balance-check",
|
|
696
843
|
"version": 1,
|
|
@@ -790,6 +937,54 @@
|
|
|
790
937
|
],
|
|
791
938
|
"path": "jobs/devops/repo-health-check.yaml"
|
|
792
939
|
},
|
|
940
|
+
{
|
|
941
|
+
"id": "review-request-nudge",
|
|
942
|
+
"version": 1,
|
|
943
|
+
"name": "Review Request Nudge",
|
|
944
|
+
"description": "Flags customers who bought a while ago and haven't been asked for a review yet. Use this if review requests only happen when someone remembers to send them.",
|
|
945
|
+
"category": "growth",
|
|
946
|
+
"tags": [
|
|
947
|
+
"growth",
|
|
948
|
+
"reviews",
|
|
949
|
+
"ecommerce"
|
|
950
|
+
],
|
|
951
|
+
"schedule": "0 9 * * *",
|
|
952
|
+
"timezone": "UTC",
|
|
953
|
+
"runner": "shell",
|
|
954
|
+
"modes": [
|
|
955
|
+
"script"
|
|
956
|
+
],
|
|
957
|
+
"compatible_agents": [
|
|
958
|
+
"generic",
|
|
959
|
+
"claude",
|
|
960
|
+
"codex"
|
|
961
|
+
],
|
|
962
|
+
"path": "jobs/growth/review-request-nudge.yaml"
|
|
963
|
+
},
|
|
964
|
+
{
|
|
965
|
+
"id": "robots-txt-check",
|
|
966
|
+
"version": 1,
|
|
967
|
+
"name": "Robots.txt Blanket-Block Check",
|
|
968
|
+
"description": "Checks that your robots.txt hasn't accidentally blocked every crawler from your entire site. Use this if a robots.txt edit has ever accidentally tanked your search traffic.",
|
|
969
|
+
"category": "content",
|
|
970
|
+
"tags": [
|
|
971
|
+
"seo",
|
|
972
|
+
"robots",
|
|
973
|
+
"crawlability"
|
|
974
|
+
],
|
|
975
|
+
"schedule": "0 8 * * *",
|
|
976
|
+
"timezone": "UTC",
|
|
977
|
+
"runner": "shell",
|
|
978
|
+
"modes": [
|
|
979
|
+
"script"
|
|
980
|
+
],
|
|
981
|
+
"compatible_agents": [
|
|
982
|
+
"generic",
|
|
983
|
+
"claude",
|
|
984
|
+
"codex"
|
|
985
|
+
],
|
|
986
|
+
"path": "jobs/content/robots-txt-check.yaml"
|
|
987
|
+
},
|
|
793
988
|
{
|
|
794
989
|
"id": "rss-feed-validate",
|
|
795
990
|
"version": 1,
|
|
@@ -913,6 +1108,30 @@
|
|
|
913
1108
|
],
|
|
914
1109
|
"path": "jobs/content/seo-meta-check.yaml"
|
|
915
1110
|
},
|
|
1111
|
+
{
|
|
1112
|
+
"id": "smoke-detector-battery-check",
|
|
1113
|
+
"version": 1,
|
|
1114
|
+
"name": "Smoke Detector Battery Check Reminder",
|
|
1115
|
+
"description": "Reminds you to test/replace smoke detector batteries on a schedule. Use this if the only time you think about smoke detectors is when one starts chirping at 3am.",
|
|
1116
|
+
"category": "home",
|
|
1117
|
+
"tags": [
|
|
1118
|
+
"home",
|
|
1119
|
+
"safety",
|
|
1120
|
+
"maintenance"
|
|
1121
|
+
],
|
|
1122
|
+
"schedule": "0 9 1 * *",
|
|
1123
|
+
"timezone": "America/Los_Angeles",
|
|
1124
|
+
"runner": "shell",
|
|
1125
|
+
"modes": [
|
|
1126
|
+
"script"
|
|
1127
|
+
],
|
|
1128
|
+
"compatible_agents": [
|
|
1129
|
+
"generic",
|
|
1130
|
+
"claude",
|
|
1131
|
+
"codex"
|
|
1132
|
+
],
|
|
1133
|
+
"path": "jobs/home/smoke-detector-battery-check.yaml"
|
|
1134
|
+
},
|
|
916
1135
|
{
|
|
917
1136
|
"id": "social-mentions-watch",
|
|
918
1137
|
"version": 1,
|
|
@@ -1084,6 +1303,30 @@
|
|
|
1084
1303
|
],
|
|
1085
1304
|
"path": "jobs/devops/uptime-ping-check.yaml"
|
|
1086
1305
|
},
|
|
1306
|
+
{
|
|
1307
|
+
"id": "visa-expiry-check",
|
|
1308
|
+
"version": 1,
|
|
1309
|
+
"name": "Visa/Residency Document Expiry Check",
|
|
1310
|
+
"description": "Warns you before a visa, residency permit, or similar document expires. Use this if you're living or working abroad and a document deadline has ever crept up on you.",
|
|
1311
|
+
"category": "travel",
|
|
1312
|
+
"tags": [
|
|
1313
|
+
"travel",
|
|
1314
|
+
"visa",
|
|
1315
|
+
"documents"
|
|
1316
|
+
],
|
|
1317
|
+
"schedule": "0 9 1 * *",
|
|
1318
|
+
"timezone": "UTC",
|
|
1319
|
+
"runner": "shell",
|
|
1320
|
+
"modes": [
|
|
1321
|
+
"script"
|
|
1322
|
+
],
|
|
1323
|
+
"compatible_agents": [
|
|
1324
|
+
"generic",
|
|
1325
|
+
"claude",
|
|
1326
|
+
"codex"
|
|
1327
|
+
],
|
|
1328
|
+
"path": "jobs/travel/visa-expiry-check.yaml"
|
|
1329
|
+
},
|
|
1087
1330
|
{
|
|
1088
1331
|
"id": "water-intake-reminder",
|
|
1089
1332
|
"version": 1,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
id: robots-txt-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: Robots.txt Blanket-Block Check
|
|
4
|
+
description: >
|
|
5
|
+
Checks that your robots.txt hasn't accidentally blocked every
|
|
6
|
+
crawler from your entire site. Use this if a robots.txt edit has
|
|
7
|
+
ever accidentally tanked your search traffic.
|
|
8
|
+
category: content
|
|
9
|
+
tags: [seo, robots, crawlability]
|
|
10
|
+
schedule: "0 8 * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
url={{robots_url}};
|
|
15
|
+
body=$(curl -sL --max-time 10 "$url");
|
|
16
|
+
[ -z "$body" ] && { echo "ERROR: could not fetch $url"; exit 1; };
|
|
17
|
+
if echo "$body" | grep -qiE "^Disallow:[[:space:]]*/[[:space:]]*$"; then
|
|
18
|
+
echo "WARNING: $url has a blanket 'Disallow: /' — this blocks all crawlers from the whole site.";
|
|
19
|
+
exit 1;
|
|
20
|
+
else
|
|
21
|
+
echo "OK: no blanket disallow-all rule found in $url";
|
|
22
|
+
fi
|
|
23
|
+
variables:
|
|
24
|
+
robots_url:
|
|
25
|
+
default: "https://example.com/robots.txt"
|
|
26
|
+
description: Full URL to your site's robots.txt.
|
|
27
|
+
compatible_agents: [generic, claude, codex]
|
|
28
|
+
notes: >
|
|
29
|
+
Zero-token. Only checks for the "block everything" footgun, not full
|
|
30
|
+
robots.txt correctness.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
id: cart-abandonment-followup
|
|
2
|
+
version: 1
|
|
3
|
+
name: Cart Abandonment Follow-up
|
|
4
|
+
description: >
|
|
5
|
+
Finds abandoned shopping carts old enough to follow up on, and can
|
|
6
|
+
draft the follow-up email for you. Use this if abandoned-cart
|
|
7
|
+
recovery is something you know you should do but never get to.
|
|
8
|
+
category: growth
|
|
9
|
+
tags: [growth, ecommerce, cart-recovery]
|
|
10
|
+
schedule: "0 10 * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: hybrid
|
|
13
|
+
command: >
|
|
14
|
+
file={{carts_file}}; wait_hours={{wait_hours}};
|
|
15
|
+
[ -f "$file" ] || { echo "ERROR: $file not found"; exit 1; };
|
|
16
|
+
now=$(date +%s);
|
|
17
|
+
tail -n +2 "$file" | while IFS=, read -r id email items abandoned followed; do
|
|
18
|
+
[ "$followed" = "yes" ] && continue;
|
|
19
|
+
a_epoch=$(date -d "$abandoned" +%s 2>/dev/null || date -j -f "%Y-%m-%d %H:%M" "$abandoned" +%s 2>/dev/null);
|
|
20
|
+
hours=$(( (now-a_epoch)/3600 ));
|
|
21
|
+
if [ "$hours" -ge "$wait_hours" ]; then echo "ABANDONED: cart $id ($email) - items: $items - ${hours}h ago"; fi
|
|
22
|
+
done
|
|
23
|
+
prompt: |
|
|
24
|
+
Look at carts abandoned more than {{wait_hours}} hours ago in
|
|
25
|
+
{{carts_file}} (CSV: cart_id,customer_email,items,abandoned_at,followed_up).
|
|
26
|
+
For each one not yet followed up:
|
|
27
|
+
1. Draft a short, friendly follow-up email offering help or a gentle
|
|
28
|
+
nudge to complete checkout.
|
|
29
|
+
2. Keep it under 100 words, no hard-sell tone.
|
|
30
|
+
script_note: >
|
|
31
|
+
`command` lists which carts are abandoned and old enough to follow up
|
|
32
|
+
on, zero tokens. `prompt` actually drafts the follow-up email copy for
|
|
33
|
+
each one.
|
|
34
|
+
variables:
|
|
35
|
+
carts_file:
|
|
36
|
+
default: "./abandoned-carts.csv"
|
|
37
|
+
description: >
|
|
38
|
+
CSV with header "cart_id,customer_email,items,abandoned_at,followed_up"
|
|
39
|
+
(abandoned_at is "YYYY-MM-DD HH:MM", followed_up is yes/no).
|
|
40
|
+
wait_hours:
|
|
41
|
+
default: 24
|
|
42
|
+
description: Wait this many hours after abandonment before flagging for follow-up.
|
|
43
|
+
compatible_agents: [claude, codex, hermes, openclaw, generic]
|
|
44
|
+
notes: >
|
|
45
|
+
You maintain abandoned-carts.csv yourself (or export it from your store
|
|
46
|
+
platform) — mark followed_up=yes after sending.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
id: review-request-nudge
|
|
2
|
+
version: 1
|
|
3
|
+
name: Review Request Nudge
|
|
4
|
+
description: >
|
|
5
|
+
Flags customers who bought a while ago and haven't been asked for a
|
|
6
|
+
review yet. Use this if review requests only happen when someone
|
|
7
|
+
remembers to send them.
|
|
8
|
+
category: growth
|
|
9
|
+
tags: [growth, reviews, ecommerce]
|
|
10
|
+
schedule: "0 9 * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
file={{orders_file}}; wait_days={{wait_days}};
|
|
15
|
+
[ -f "$file" ] || { echo "ERROR: $file not found"; exit 1; };
|
|
16
|
+
today=$(date +%s);
|
|
17
|
+
tail -n +2 "$file" | while IFS=, read -r id customer purchased requested; do
|
|
18
|
+
[ "$requested" = "yes" ] && continue;
|
|
19
|
+
p_epoch=$(date -j -f %Y-%m-%d "$purchased" +%s 2>/dev/null || date -d "$purchased" +%s);
|
|
20
|
+
days=$(( (today-p_epoch)/86400 ));
|
|
21
|
+
if [ "$days" -ge "$wait_days" ]; then echo "SEND REVIEW REQUEST: order $id ($customer), purchased $days day(s) ago"; fi
|
|
22
|
+
done
|
|
23
|
+
variables:
|
|
24
|
+
orders_file:
|
|
25
|
+
default: "./orders.csv"
|
|
26
|
+
description: >
|
|
27
|
+
CSV with header "order_id,customer,purchase_date,review_requested"
|
|
28
|
+
(purchase_date is YYYY-MM-DD, review_requested is yes/no).
|
|
29
|
+
wait_days:
|
|
30
|
+
default: 7
|
|
31
|
+
description: Wait this many days after purchase before flagging for a review request.
|
|
32
|
+
compatible_agents: [generic, claude, codex]
|
|
33
|
+
notes: >
|
|
34
|
+
Zero-token. You maintain orders.csv yourself (mark review_requested=yes
|
|
35
|
+
after sending) — doesn't integrate with any store platform directly.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
id: hvac-filter-reminder
|
|
2
|
+
version: 1
|
|
3
|
+
name: HVAC Filter Change Reminder
|
|
4
|
+
description: >
|
|
5
|
+
Reminds you to change your HVAC filter based on how long it's been.
|
|
6
|
+
Use this if you've ever found a filter so clogged you forgot it was
|
|
7
|
+
ever white.
|
|
8
|
+
category: home
|
|
9
|
+
tags: [home, hvac, maintenance]
|
|
10
|
+
schedule: "0 9 1 * *"
|
|
11
|
+
timezone: "America/Los_Angeles"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
last={{last_changed_date}}; interval={{interval_months}};
|
|
15
|
+
last_epoch=$(date -j -f %Y-%m-%d "$last" +%s 2>/dev/null || date -d "$last" +%s);
|
|
16
|
+
today_epoch=$(date +%s);
|
|
17
|
+
days_since=$(( (today_epoch-last_epoch)/86400 ));
|
|
18
|
+
interval_days=$(( interval * 30 ));
|
|
19
|
+
if [ "$days_since" -ge "$interval_days" ]; then echo "REMINDER: HVAC filter last changed $days_since day(s) ago (every ${interval} months) — change it.";
|
|
20
|
+
else echo "OK: filter changed $days_since day(s) ago, due again around day $interval_days."; fi
|
|
21
|
+
variables:
|
|
22
|
+
last_changed_date:
|
|
23
|
+
default: "2026-01-01"
|
|
24
|
+
description: Date (YYYY-MM-DD) you last changed the filter — update this yourself.
|
|
25
|
+
interval_months:
|
|
26
|
+
default: 3
|
|
27
|
+
description: How often to change the filter, in months.
|
|
28
|
+
compatible_agents: [generic, claude, codex]
|
|
29
|
+
notes: Zero-token. You update last_changed_date yourself each time you actually change it.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
id: plant-watering-reminder
|
|
2
|
+
version: 1
|
|
3
|
+
name: Plant Watering Reminder
|
|
4
|
+
description: >
|
|
5
|
+
Reminds you to water a specific plant once it's due. Use this if
|
|
6
|
+
you've ever lost a plant to "I'll water it tomorrow."
|
|
7
|
+
category: home
|
|
8
|
+
tags: [home, plants, reminder]
|
|
9
|
+
schedule: "0 9 * * *"
|
|
10
|
+
timezone: "America/Los_Angeles"
|
|
11
|
+
runner: shell
|
|
12
|
+
command: >
|
|
13
|
+
last={{last_watered_date}}; interval={{water_interval_days}};
|
|
14
|
+
last_epoch=$(date -j -f %Y-%m-%d "$last" +%s 2>/dev/null || date -d "$last" +%s);
|
|
15
|
+
today_epoch=$(date +%s);
|
|
16
|
+
days_since=$(( (today_epoch-last_epoch)/86400 ));
|
|
17
|
+
if [ "$days_since" -ge "$interval" ]; then echo "REMINDER: water {{plant_name}} ($days_since day(s) since last watering, every $interval day(s)).";
|
|
18
|
+
else echo "OK: {{plant_name}} watered $days_since day(s) ago, next due in $(( interval - days_since )) day(s)."; fi
|
|
19
|
+
variables:
|
|
20
|
+
plant_name:
|
|
21
|
+
default: "your plant"
|
|
22
|
+
description: Which plant this reminder is for.
|
|
23
|
+
water_interval_days:
|
|
24
|
+
default: 7
|
|
25
|
+
description: How often to water it, in days.
|
|
26
|
+
last_watered_date:
|
|
27
|
+
default: "2026-01-01"
|
|
28
|
+
description: Date (YYYY-MM-DD) you last watered it — update this yourself.
|
|
29
|
+
compatible_agents: [generic, claude, codex]
|
|
30
|
+
notes: Zero-token. One job per plant — copy it and adjust plant_name/interval for each.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
id: smoke-detector-battery-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: Smoke Detector Battery Check Reminder
|
|
4
|
+
description: >
|
|
5
|
+
Reminds you to test/replace smoke detector batteries on a schedule.
|
|
6
|
+
Use this if the only time you think about smoke detectors is when one
|
|
7
|
+
starts chirping at 3am.
|
|
8
|
+
category: home
|
|
9
|
+
tags: [home, safety, maintenance]
|
|
10
|
+
schedule: "0 9 1 * *"
|
|
11
|
+
timezone: "America/Los_Angeles"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
last={{last_tested_date}}; interval={{interval_months}};
|
|
15
|
+
last_epoch=$(date -j -f %Y-%m-%d "$last" +%s 2>/dev/null || date -d "$last" +%s);
|
|
16
|
+
today_epoch=$(date +%s);
|
|
17
|
+
days_since=$(( (today_epoch-last_epoch)/86400 ));
|
|
18
|
+
interval_days=$(( interval * 30 ));
|
|
19
|
+
if [ "$days_since" -ge "$interval_days" ]; then echo "REMINDER: smoke detectors last tested $days_since day(s) ago (every ${interval} months) — test/replace batteries.";
|
|
20
|
+
else echo "OK: tested $days_since day(s) ago, due again around day $interval_days."; fi
|
|
21
|
+
variables:
|
|
22
|
+
last_tested_date:
|
|
23
|
+
default: "2026-01-01"
|
|
24
|
+
description: Date (YYYY-MM-DD) you last tested/changed batteries — update this yourself.
|
|
25
|
+
interval_months:
|
|
26
|
+
default: 6
|
|
27
|
+
description: How often to test, in months.
|
|
28
|
+
compatible_agents: [generic, claude, codex]
|
|
29
|
+
notes: Zero-token. You update last_tested_date yourself each time you actually test.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
id: certificate-transparency-watch
|
|
2
|
+
version: 1
|
|
3
|
+
name: Certificate Transparency Watch
|
|
4
|
+
description: >
|
|
5
|
+
Checks public Certificate Transparency logs for new TLS certs issued
|
|
6
|
+
for your domain and flags any you didn't expect. Use this if you want
|
|
7
|
+
an early warning for someone issuing a cert for your domain without
|
|
8
|
+
your knowledge (a common precursor to phishing/MITM setups).
|
|
9
|
+
category: security
|
|
10
|
+
tags: [security, tls, certificate-transparency]
|
|
11
|
+
schedule: "0 */12 * * *"
|
|
12
|
+
timezone: "UTC"
|
|
13
|
+
runner: shell
|
|
14
|
+
command: >
|
|
15
|
+
domain={{domain}}; state={{state_file}};
|
|
16
|
+
current=$(curl -s "https://crt.sh/?q=${domain}&output=json" | grep -o '"id":[0-9]*' | sort -u);
|
|
17
|
+
if [ ! -f "$state" ]; then echo "$current" > "$state"; echo "no baseline found — saved current cert IDs as the baseline ($(echo "$current" | wc -l | tr -d ' ') certs)"; exit 0; fi;
|
|
18
|
+
new=$(comm -13 <(sort "$state") <(echo "$current" | sort));
|
|
19
|
+
if [ -n "$new" ]; then echo "NEW CERT(S) issued for $domain since last check:"; echo "$new"; echo "$current" > "$state";
|
|
20
|
+
else echo "OK: no new certs for $domain since last check"; fi
|
|
21
|
+
variables:
|
|
22
|
+
domain:
|
|
23
|
+
default: "example.com"
|
|
24
|
+
description: Domain to watch in Certificate Transparency logs.
|
|
25
|
+
state_file:
|
|
26
|
+
default: "./.ct-watch-state"
|
|
27
|
+
description: File this job uses to remember which cert IDs it's already seen.
|
|
28
|
+
compatible_agents: [generic, claude, codex]
|
|
29
|
+
notes: >
|
|
30
|
+
Zero-token. Uses the public crt.sh API (rate limits may apply).
|
|
31
|
+
Requires bash (process substitution).
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
id: flight-checkin-reminder
|
|
2
|
+
version: 1
|
|
3
|
+
name: Flight Check-in Reminder
|
|
4
|
+
description: >
|
|
5
|
+
Reminds you when online check-in opens for an upcoming flight. Use
|
|
6
|
+
this if you've ever missed the good seats because check-in opened
|
|
7
|
+
while you were asleep.
|
|
8
|
+
category: travel
|
|
9
|
+
tags: [travel, flight, reminder]
|
|
10
|
+
schedule: "0 * * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
flight="{{flight_datetime}}"; hours_before={{checkin_hours_before}};
|
|
15
|
+
flight_epoch=$(date -j -f "%Y-%m-%d %H:%M" "$flight" +%s 2>/dev/null || date -d "$flight" +%s);
|
|
16
|
+
now_epoch=$(date +%s);
|
|
17
|
+
hours_left=$(( (flight_epoch-now_epoch)/3600 ));
|
|
18
|
+
if [ "$hours_left" -le 0 ]; then echo "note: flight time has passed — update flight_datetime for your next trip.";
|
|
19
|
+
elif [ "$hours_left" -le "$hours_before" ]; then echo "REMINDER: check in for your flight — departs in ${hours_left}h ($flight).";
|
|
20
|
+
else echo "OK: ${hours_left}h until flight ($flight), check-in opens around ${hours_before}h before departure."; fi
|
|
21
|
+
variables:
|
|
22
|
+
flight_datetime:
|
|
23
|
+
default: "2026-12-31 08:00"
|
|
24
|
+
description: Flight departure date and time ("YYYY-MM-DD HH:MM", local to the schedule's timezone).
|
|
25
|
+
checkin_hours_before:
|
|
26
|
+
default: 24
|
|
27
|
+
description: How many hours before departure check-in typically opens for your airline.
|
|
28
|
+
compatible_agents: [generic, claude, codex]
|
|
29
|
+
notes: >
|
|
30
|
+
Zero-token. Runs hourly since it's a time-sensitive window — update
|
|
31
|
+
flight_datetime for each new trip.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
id: passport-expiry-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: Passport Expiry Check
|
|
4
|
+
description: >
|
|
5
|
+
Warns you before your passport expires — including the "6 months
|
|
6
|
+
validity required" rule many countries enforce at the border. Use
|
|
7
|
+
this if you've ever booked a trip and only checked your passport
|
|
8
|
+
date after buying the ticket.
|
|
9
|
+
category: travel
|
|
10
|
+
tags: [travel, passport, documents]
|
|
11
|
+
schedule: "0 9 1 * *"
|
|
12
|
+
timezone: "UTC"
|
|
13
|
+
runner: shell
|
|
14
|
+
command: >
|
|
15
|
+
expiry={{passport_expiry_date}}; warn_months={{warn_months}};
|
|
16
|
+
expiry_epoch=$(date -j -f %Y-%m-%d "$expiry" +%s 2>/dev/null || date -d "$expiry" +%s);
|
|
17
|
+
today_epoch=$(date +%s);
|
|
18
|
+
days_left=$(( (expiry_epoch-today_epoch)/86400 ));
|
|
19
|
+
warn_days=$(( warn_months * 30 ));
|
|
20
|
+
if [ "$days_left" -le 0 ]; then echo "EXPIRED: passport expired on $expiry — renew immediately."; exit 1;
|
|
21
|
+
elif [ "$days_left" -le "$warn_days" ]; then echo "WARNING: passport expires in $days_left day(s) ($expiry) — many countries require ${warn_months} month(s) of remaining validity to enter."; exit 1;
|
|
22
|
+
else echo "OK: passport valid, $days_left day(s) until expiry ($expiry)."; fi
|
|
23
|
+
variables:
|
|
24
|
+
passport_expiry_date:
|
|
25
|
+
default: "2030-01-01"
|
|
26
|
+
description: Date (YYYY-MM-DD) your passport expires.
|
|
27
|
+
warn_months:
|
|
28
|
+
default: 6
|
|
29
|
+
description: Start warning this many months before expiry (6 is the common border-entry rule).
|
|
30
|
+
compatible_agents: [generic, claude, codex]
|
|
31
|
+
notes: Zero-token. Update passport_expiry_date after renewal.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
id: visa-expiry-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: Visa/Residency Document Expiry Check
|
|
4
|
+
description: >
|
|
5
|
+
Warns you before a visa, residency permit, or similar document
|
|
6
|
+
expires. Use this if you're living or working abroad and a document
|
|
7
|
+
deadline has ever crept up on you.
|
|
8
|
+
category: travel
|
|
9
|
+
tags: [travel, visa, documents]
|
|
10
|
+
schedule: "0 9 1 * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
name="{{doc_name}}"; expiry={{expiry_date}}; warn={{warn_days}};
|
|
15
|
+
expiry_epoch=$(date -j -f %Y-%m-%d "$expiry" +%s 2>/dev/null || date -d "$expiry" +%s);
|
|
16
|
+
today_epoch=$(date +%s);
|
|
17
|
+
days_left=$(( (expiry_epoch-today_epoch)/86400 ));
|
|
18
|
+
if [ "$days_left" -le 0 ]; then echo "EXPIRED: $name expired on $expiry."; exit 1;
|
|
19
|
+
elif [ "$days_left" -le "$warn" ]; then echo "WARNING: $name expires in $days_left day(s) ($expiry)."; exit 1;
|
|
20
|
+
else echo "OK: $name valid, $days_left day(s) until expiry."; fi
|
|
21
|
+
variables:
|
|
22
|
+
doc_name:
|
|
23
|
+
default: "visa"
|
|
24
|
+
description: What document this is (visa, residency permit, work permit, etc).
|
|
25
|
+
expiry_date:
|
|
26
|
+
default: "2027-01-01"
|
|
27
|
+
description: Date (YYYY-MM-DD) the document expires.
|
|
28
|
+
warn_days:
|
|
29
|
+
default: 30
|
|
30
|
+
description: Start warning this many days before expiry.
|
|
31
|
+
compatible_agents: [generic, claude, codex]
|
|
32
|
+
notes: Zero-token. One job per document — copy it and adjust for each document you're tracking.
|