@wonsukchoi/crondex 0.5.0 → 0.6.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/catalog.json +576 -1
- package/jobs/content/canonical-tag-check.yaml +25 -0
- package/jobs/content/sitemap-freshness-check.yaml +31 -0
- package/jobs/content/stale-post-audit.yaml +28 -0
- package/jobs/devops/error-rate-spike-watch.yaml +43 -0
- package/jobs/devops/feature-flag-staleness-audit.yaml +30 -0
- package/jobs/devops/terraform-drift-check.yaml +24 -0
- package/jobs/finance/budget-overspend-check.yaml +29 -0
- package/jobs/finance/fx-rate-watch.yaml +33 -0
- package/jobs/growth/churn-risk-watch.yaml +33 -0
- package/jobs/growth/trial-expiring-nudge.yaml +33 -0
- package/jobs/home/car-maintenance-due-reminder.yaml +30 -0
- package/jobs/learning/cert-renewal-reminder.yaml +30 -0
- package/jobs/learning/conference-cfp-deadline-reminder.yaml +42 -0
- package/jobs/personal/medication-refill-reminder.yaml +30 -0
- package/jobs/productivity/calendar-double-booking-check.yaml +21 -0
- package/jobs/productivity/stale-todo-sweep.yaml +26 -0
- package/jobs/security/cve-watch.yaml +27 -0
- package/jobs/security/iam-key-rotation-reminder.yaml +27 -0
- package/jobs/security/s3-public-bucket-check.yaml +20 -0
- package/jobs/team/oncall-handoff-reminder.yaml +26 -0
- package/jobs/team/team-anniversary-reminder.yaml +22 -0
- package/jobs/travel/frequent-flyer-miles-expiry.yaml +30 -0
- package/jobs/travel/travel-insurance-expiry-check.yaml +26 -0
- package/package.json +1 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
id: sitemap-freshness-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: Sitemap Freshness Check
|
|
4
|
+
description: >
|
|
5
|
+
Checks that your sitemap.xml was actually regenerated recently and isn't
|
|
6
|
+
quietly stuck on an old snapshot. Use this if your sitemap is generated
|
|
7
|
+
by a build step that's ever silently failed or skipped.
|
|
8
|
+
category: content
|
|
9
|
+
tags: [seo, sitemap, freshness]
|
|
10
|
+
schedule: "0 7 * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
lastmod=$(curl -s {{sitemap_url}} | grep -o '<lastmod>[^<]*' | sed 's/<lastmod>//' | sort -r | head -n1);
|
|
15
|
+
if [ -z "$lastmod" ]; then echo "WARNING: could not find any <lastmod> entries in {{sitemap_url}}"; exit 1;
|
|
16
|
+
else
|
|
17
|
+
lastmod_ts=$(date -d "$lastmod" +%s 2>/dev/null || date -jf "%Y-%m-%d" "${lastmod%%T*}" +%s 2>/dev/null);
|
|
18
|
+
now_ts=$(date +%s);
|
|
19
|
+
age_days=$(( (now_ts - lastmod_ts) / 86400 ));
|
|
20
|
+
if [ "$age_days" -ge "{{max_age_days}}" ]; then echo "WARNING: newest sitemap entry is $age_days days old"; exit 1;
|
|
21
|
+
else echo "OK: newest sitemap entry is $age_days days old"; fi
|
|
22
|
+
fi
|
|
23
|
+
variables:
|
|
24
|
+
sitemap_url:
|
|
25
|
+
default: "https://example.com/sitemap.xml"
|
|
26
|
+
description: URL of the sitemap to check.
|
|
27
|
+
max_age_days:
|
|
28
|
+
default: 14
|
|
29
|
+
description: Days since the newest lastmod entry before it's flagged stale.
|
|
30
|
+
compatible_agents: [generic, claude, codex]
|
|
31
|
+
notes: Assumes at least one <lastmod> tag exists in the sitemap; sitemap index files with nested sitemaps aren't followed.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
id: stale-post-audit
|
|
2
|
+
version: 1
|
|
3
|
+
name: Stale Post Audit
|
|
4
|
+
description: >
|
|
5
|
+
Flags published posts that haven't been touched in a long time, as
|
|
6
|
+
candidates for a refresh. Use this if old content quietly rots (dead
|
|
7
|
+
screenshots, outdated advice) while still ranking and getting traffic.
|
|
8
|
+
category: content
|
|
9
|
+
tags: [content, seo, maintenance]
|
|
10
|
+
schedule: "0 8 1 * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: agent-prompt
|
|
13
|
+
prompt: |
|
|
14
|
+
Review posts/pages under {{content_dir}}.
|
|
15
|
+
1. For each, find the last modified date (git log or frontmatter date).
|
|
16
|
+
2. Flag any not updated in more than {{stale_months}} months.
|
|
17
|
+
3. For the flagged ones, note anything obviously outdated (broken
|
|
18
|
+
screenshots, version numbers, dead links) if visible in the content.
|
|
19
|
+
4. Report the list ranked oldest-first.
|
|
20
|
+
variables:
|
|
21
|
+
content_dir:
|
|
22
|
+
default: "content/posts"
|
|
23
|
+
description: Directory containing published content.
|
|
24
|
+
stale_months:
|
|
25
|
+
default: 12
|
|
26
|
+
description: Months since last update before a post is flagged.
|
|
27
|
+
compatible_agents: [claude, codex, hermes, openclaw, generic]
|
|
28
|
+
notes: No generic script mode — "last modified" via git log is easy in shell, but judging what's outdated needs an agent reading the content.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
id: error-rate-spike-watch
|
|
2
|
+
version: 1
|
|
3
|
+
name: Error Rate Spike Watch
|
|
4
|
+
description: >
|
|
5
|
+
Checks your error tracker's recent error count against a threshold and
|
|
6
|
+
flags a spike. Use this if a bad deploy has ever quietly spiked errors
|
|
7
|
+
for hours before anyone noticed.
|
|
8
|
+
category: devops
|
|
9
|
+
tags: [errors, monitoring, alerting]
|
|
10
|
+
schedule: "*/15 * * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: hybrid
|
|
13
|
+
command: >
|
|
14
|
+
if [ -n "$SENTRY_AUTH_TOKEN" ] && [ -n "{{sentry_project}}" ]; then
|
|
15
|
+
count=$(curl -s -H "Authorization: Bearer $SENTRY_AUTH_TOKEN" "https://sentry.io/api/0/projects/{{sentry_org}}/{{sentry_project}}/events/?statsPeriod=15m" | grep -o '"id"' | wc -l | tr -d ' ');
|
|
16
|
+
if [ "$count" -ge "{{threshold}}" ]; then echo "WARNING: $count errors in last 15m (threshold {{threshold}})"; exit 1;
|
|
17
|
+
else echo "OK: $count errors in last 15m"; fi
|
|
18
|
+
else
|
|
19
|
+
echo "SENTRY_AUTH_TOKEN or sentry_project not set — use agent-prompt mode instead";
|
|
20
|
+
fi
|
|
21
|
+
prompt: |
|
|
22
|
+
Check the error tracker (Sentry, Rollbar, Bugsnag, or whatever this
|
|
23
|
+
project uses) for {{sentry_project}} over the last 15 minutes.
|
|
24
|
+
1. Compare current error volume to the typical rate for this time of day.
|
|
25
|
+
2. If it's spiking (well above {{threshold}} events, or a clear anomaly
|
|
26
|
+
vs. baseline), alert with the top offending error and when it started.
|
|
27
|
+
3. If normal, report the count in one line.
|
|
28
|
+
script_note: >
|
|
29
|
+
`command` only supports Sentry's REST API with a raw event count
|
|
30
|
+
threshold. `prompt` works with any error tracker and can reason about
|
|
31
|
+
baseline vs. anomaly instead of a flat threshold.
|
|
32
|
+
variables:
|
|
33
|
+
sentry_org:
|
|
34
|
+
default: "your-org"
|
|
35
|
+
description: Sentry organization slug.
|
|
36
|
+
sentry_project:
|
|
37
|
+
default: "your-project"
|
|
38
|
+
description: Sentry project slug.
|
|
39
|
+
threshold:
|
|
40
|
+
default: 50
|
|
41
|
+
description: Error count in the window that counts as a spike.
|
|
42
|
+
compatible_agents: [claude, codex, hermes, openclaw, generic]
|
|
43
|
+
notes: Script mode needs SENTRY_AUTH_TOKEN in the environment; scoped read access to project events is enough.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
id: feature-flag-staleness-audit
|
|
2
|
+
version: 1
|
|
3
|
+
name: Feature Flag Staleness Audit
|
|
4
|
+
description: >
|
|
5
|
+
Flags feature flags that have been at 100% (or 0%) rollout for a long
|
|
6
|
+
time and never cleaned up. Use this if your flag list has become a
|
|
7
|
+
graveyard of decisions nobody removed the scaffolding for.
|
|
8
|
+
category: devops
|
|
9
|
+
tags: [feature-flags, cleanup, tech-debt]
|
|
10
|
+
schedule: "0 9 * * 1"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: agent-prompt
|
|
13
|
+
prompt: |
|
|
14
|
+
Audit feature flags in {{flag_provider_hint}} (or the flags config file
|
|
15
|
+
in this repo if flags are managed in code).
|
|
16
|
+
1. List flags that have been fully rolled out (100%) or fully killed (0%)
|
|
17
|
+
for more than {{stale_days}} days.
|
|
18
|
+
2. For each, note whether the flag and its dead branch are still
|
|
19
|
+
referenced in code.
|
|
20
|
+
3. Report the list, ranked by how long they've been stale, as candidates
|
|
21
|
+
for removal.
|
|
22
|
+
variables:
|
|
23
|
+
flag_provider_hint:
|
|
24
|
+
default: "LaunchDarkly"
|
|
25
|
+
description: Name of the feature flag system/provider in use (e.g. LaunchDarkly, Unleash, in-repo config).
|
|
26
|
+
stale_days:
|
|
27
|
+
default: 60
|
|
28
|
+
description: Days at a terminal rollout state before a flag counts as stale.
|
|
29
|
+
compatible_agents: [claude, codex, hermes, openclaw, generic]
|
|
30
|
+
notes: No generic script mode — flag providers have wildly different APIs, and "still referenced in code" needs a code-aware agent.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
id: terraform-drift-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: Terraform Drift Check
|
|
4
|
+
description: >
|
|
5
|
+
Runs a Terraform plan and flags it if there's drift between your state
|
|
6
|
+
and actual infrastructure. Use this if you've ever had someone click
|
|
7
|
+
around in a cloud console and quietly break parity with your IaC.
|
|
8
|
+
category: devops
|
|
9
|
+
tags: [terraform, infrastructure, drift]
|
|
10
|
+
schedule: "0 7 * * 1-5"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
cd {{terraform_dir}} && terraform plan -detailed-exitcode -no-color -input=false > /tmp/tf-plan.out 2>&1;
|
|
15
|
+
code=$?;
|
|
16
|
+
if [ "$code" -eq 2 ]; then echo "DRIFT DETECTED in {{terraform_dir}}:"; tail -n 40 /tmp/tf-plan.out; exit 1;
|
|
17
|
+
elif [ "$code" -eq 0 ]; then echo "OK: no drift in {{terraform_dir}}";
|
|
18
|
+
else echo "ERROR: terraform plan failed"; tail -n 40 /tmp/tf-plan.out; exit 1; fi
|
|
19
|
+
variables:
|
|
20
|
+
terraform_dir:
|
|
21
|
+
default: "."
|
|
22
|
+
description: Path to the Terraform root module to check.
|
|
23
|
+
compatible_agents: [generic, claude, codex]
|
|
24
|
+
notes: Requires terraform CLI and valid provider credentials already configured in the environment.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
id: budget-overspend-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: Budget Overspend Check
|
|
4
|
+
description: >
|
|
5
|
+
Compares this month's spend in a budget category against your limit and
|
|
6
|
+
warns if you're over. Use this if you set budgets once and then never
|
|
7
|
+
actually check them until the month's already blown.
|
|
8
|
+
category: finance
|
|
9
|
+
tags: [budget, spending, finance]
|
|
10
|
+
schedule: "0 9 * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
spent=$(awk -F, -v month="$(date +%Y-%m)" -v cat="{{category}}" '$1 ~ month && $2 == cat {sum += $3} END {print sum+0}' {{transactions_csv}});
|
|
15
|
+
limit={{budget_limit}};
|
|
16
|
+
if awk "BEGIN{exit !($spent >= $limit)}"; then echo "WARNING: {{category}} spend \$$spent has hit/exceeded budget \$$limit this month"; exit 1;
|
|
17
|
+
else echo "OK: {{category}} spend \$$spent, budget \$$limit"; fi
|
|
18
|
+
variables:
|
|
19
|
+
transactions_csv:
|
|
20
|
+
default: "transactions.csv"
|
|
21
|
+
description: "CSV of transactions with columns: date(YYYY-MM-DD),category,amount."
|
|
22
|
+
category:
|
|
23
|
+
default: "dining"
|
|
24
|
+
description: Budget category to check.
|
|
25
|
+
budget_limit:
|
|
26
|
+
default: 300
|
|
27
|
+
description: Monthly budget limit for this category, in your currency.
|
|
28
|
+
compatible_agents: [generic, claude, codex]
|
|
29
|
+
notes: Expects a plain CSV export; point transactions_csv at wherever your bank/budgeting tool exports to.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
id: fx-rate-watch
|
|
2
|
+
version: 1
|
|
3
|
+
name: FX Rate Watch
|
|
4
|
+
description: >
|
|
5
|
+
Checks a currency pair's exchange rate and alerts when it crosses a
|
|
6
|
+
threshold you set. Use this if you're timing a transfer, payment, or
|
|
7
|
+
purchase around a favorable rate and don't want to check manually every day.
|
|
8
|
+
category: finance
|
|
9
|
+
tags: [finance, currency, fx]
|
|
10
|
+
schedule: "0 8 * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
rate=$(curl -s "https://api.exchangerate.host/latest?base={{from_currency}}&symbols={{to_currency}}" | grep -o '"{{to_currency}}":[0-9.]*' | cut -d: -f2);
|
|
15
|
+
if [ -z "$rate" ]; then echo "ERROR: could not fetch rate for {{from_currency}}/{{to_currency}}"; exit 1; fi;
|
|
16
|
+
if awk "BEGIN{exit !($rate {{comparison}} {{target_rate}})}"; then
|
|
17
|
+
echo "ALERT: {{from_currency}}/{{to_currency}} is $rate ({{comparison}} {{target_rate}})";
|
|
18
|
+
else echo "OK: {{from_currency}}/{{to_currency}} is $rate"; fi
|
|
19
|
+
variables:
|
|
20
|
+
from_currency:
|
|
21
|
+
default: "USD"
|
|
22
|
+
description: Base currency code.
|
|
23
|
+
to_currency:
|
|
24
|
+
default: "EUR"
|
|
25
|
+
description: Target currency code.
|
|
26
|
+
target_rate:
|
|
27
|
+
default: 0.95
|
|
28
|
+
description: Threshold rate to compare against.
|
|
29
|
+
comparison:
|
|
30
|
+
default: "<="
|
|
31
|
+
description: "Comparison operator for triggering the alert: <=, >=, <, or >."
|
|
32
|
+
compatible_agents: [generic, claude, codex]
|
|
33
|
+
notes: Uses the free exchangerate.host API; swap in another FX API if you need higher rate limits or historical accuracy.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
id: churn-risk-watch
|
|
2
|
+
version: 1
|
|
3
|
+
name: Churn Risk Watch
|
|
4
|
+
description: >
|
|
5
|
+
Flags accounts whose usage has dropped off sharply, before they actually
|
|
6
|
+
cancel. Use this if you only ever find out someone churned after the
|
|
7
|
+
cancellation email arrives.
|
|
8
|
+
category: growth
|
|
9
|
+
tags: [growth, churn, retention]
|
|
10
|
+
schedule: "0 9 * * 1"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: agent-prompt
|
|
13
|
+
prompt: |
|
|
14
|
+
Review usage/activity data (from {{analytics_hint}} or the database) for
|
|
15
|
+
paying accounts.
|
|
16
|
+
1. Compare each account's activity in the last {{recent_days}} days to
|
|
17
|
+
their prior baseline.
|
|
18
|
+
2. Flag accounts with a drop of {{drop_threshold_pct}}% or more as churn
|
|
19
|
+
risks.
|
|
20
|
+
3. Report the flagged accounts ranked by drop size, with their plan
|
|
21
|
+
value, so outreach can be prioritized.
|
|
22
|
+
variables:
|
|
23
|
+
analytics_hint:
|
|
24
|
+
default: "product analytics tool (e.g. Mixpanel, PostHog, Amplitude)"
|
|
25
|
+
description: Where usage/activity data lives.
|
|
26
|
+
recent_days:
|
|
27
|
+
default: 14
|
|
28
|
+
description: Recent window to compare against baseline.
|
|
29
|
+
drop_threshold_pct:
|
|
30
|
+
default: 50
|
|
31
|
+
description: Percent drop in activity that counts as churn risk.
|
|
32
|
+
compatible_agents: [claude, codex, hermes, openclaw, generic]
|
|
33
|
+
notes: No generic script mode — "baseline vs. recent activity" needs querying an analytics source and judgment on what counts as a meaningful drop.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
id: trial-expiring-nudge
|
|
2
|
+
version: 1
|
|
3
|
+
name: Trial Expiring Nudge
|
|
4
|
+
description: >
|
|
5
|
+
Finds trial users about to expire who haven't upgraded yet, and can
|
|
6
|
+
draft the nudge email. Use this if trial-to-paid conversion nudges only
|
|
7
|
+
happen when someone remembers to send them.
|
|
8
|
+
category: growth
|
|
9
|
+
tags: [growth, trials, conversion]
|
|
10
|
+
schedule: "0 10 * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: hybrid
|
|
13
|
+
command: >
|
|
14
|
+
psql "{{database_url}}" -t -c "select email, trial_ends_at from users where trial_ends_at between now() and now() + interval '{{lookahead_days}} days' and plan = 'trial';"
|
|
15
|
+
prompt: |
|
|
16
|
+
Find users whose trial ends within the next {{lookahead_days}} days and
|
|
17
|
+
who haven't upgraded to a paid plan (query {{database_url}} or the
|
|
18
|
+
billing system).
|
|
19
|
+
1. List each user with their trial end date.
|
|
20
|
+
2. Draft a short, friendly nudge email for each, mentioning what they'd
|
|
21
|
+
lose access to and a clear upgrade link. Don't send — draft only.
|
|
22
|
+
script_note: >
|
|
23
|
+
`command` lists trial-ending users from Postgres with zero tokens.
|
|
24
|
+
`prompt` also drafts the nudge email per user, which needs an LLM.
|
|
25
|
+
variables:
|
|
26
|
+
database_url:
|
|
27
|
+
default: "postgres://user:pass@host:5432/db"
|
|
28
|
+
description: Connection string for the users/billing database.
|
|
29
|
+
lookahead_days:
|
|
30
|
+
default: 3
|
|
31
|
+
description: How many days ahead to look for trial expirations.
|
|
32
|
+
compatible_agents: [claude, codex, hermes, openclaw, generic]
|
|
33
|
+
notes: Script mode assumes a `users` table with `trial_ends_at` and `plan` columns — adjust the query to your schema.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
id: car-maintenance-due-reminder
|
|
2
|
+
version: 1
|
|
3
|
+
name: Car Maintenance Due Reminder
|
|
4
|
+
description: >
|
|
5
|
+
Warns you when a car maintenance task (oil change, registration, etc.)
|
|
6
|
+
is coming due by date. Use this if you've ever found out your
|
|
7
|
+
registration expired because a sticker in the mail got ignored.
|
|
8
|
+
category: home
|
|
9
|
+
tags: [home, car, maintenance]
|
|
10
|
+
schedule: "0 9 * * 1"
|
|
11
|
+
timezone: "America/Los_Angeles"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
today=$(date +%s);
|
|
15
|
+
due_ts=$(date -d "{{due_date}}" +%s 2>/dev/null || date -jf "%Y-%m-%d" "{{due_date}}" +%s);
|
|
16
|
+
days_left=$(( (due_ts - today) / 86400 ));
|
|
17
|
+
if [ "$days_left" -le "{{warn_days}}" ]; then echo "WARNING: {{task_name}} due in $days_left days ({{due_date}})"; exit 1;
|
|
18
|
+
else echo "OK: {{task_name}} due in $days_left days"; fi
|
|
19
|
+
variables:
|
|
20
|
+
task_name:
|
|
21
|
+
default: "oil change"
|
|
22
|
+
description: Name of the maintenance task to track.
|
|
23
|
+
due_date:
|
|
24
|
+
default: "2026-09-01"
|
|
25
|
+
description: Date the task is due (YYYY-MM-DD).
|
|
26
|
+
warn_days:
|
|
27
|
+
default: 7
|
|
28
|
+
description: Days before due date to start warning.
|
|
29
|
+
compatible_agents: [generic, claude, codex]
|
|
30
|
+
notes: One task per job instance — schedule multiple copies with different task_name/due_date for oil change, registration, inspection, etc.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
id: cert-renewal-reminder
|
|
2
|
+
version: 1
|
|
3
|
+
name: Professional Certification Renewal Reminder
|
|
4
|
+
description: >
|
|
5
|
+
Warns you before a professional certification expires or its renewal
|
|
6
|
+
window opens. Use this if you've ever let a cert lapse and had to retake
|
|
7
|
+
an exam that a renewal course would've avoided.
|
|
8
|
+
category: learning
|
|
9
|
+
tags: [learning, certification, renewal]
|
|
10
|
+
schedule: "0 9 1 * *"
|
|
11
|
+
timezone: "America/Los_Angeles"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
today=$(date +%s);
|
|
15
|
+
expiry_ts=$(date -d "{{expiry_date}}" +%s 2>/dev/null || date -jf "%Y-%m-%d" "{{expiry_date}}" +%s);
|
|
16
|
+
days_left=$(( (expiry_ts - today) / 86400 ));
|
|
17
|
+
if [ "$days_left" -le "{{warn_days}}" ]; then echo "WARNING: {{cert_name}} expires in $days_left days ({{expiry_date}})"; exit 1;
|
|
18
|
+
else echo "OK: {{cert_name}} expires in $days_left days"; fi
|
|
19
|
+
variables:
|
|
20
|
+
cert_name:
|
|
21
|
+
default: "your certification"
|
|
22
|
+
description: Name of the certification to track.
|
|
23
|
+
expiry_date:
|
|
24
|
+
default: "2027-01-01"
|
|
25
|
+
description: Certification expiry date (YYYY-MM-DD).
|
|
26
|
+
warn_days:
|
|
27
|
+
default: 60
|
|
28
|
+
description: Days before expiry to start warning.
|
|
29
|
+
compatible_agents: [generic, claude, codex]
|
|
30
|
+
notes: Manual expiry_date input — update after each renewal cycle.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
id: conference-cfp-deadline-reminder
|
|
2
|
+
version: 1
|
|
3
|
+
name: Conference CFP Deadline Reminder
|
|
4
|
+
description: >
|
|
5
|
+
Warns you before a conference's call-for-papers deadline, and can help
|
|
6
|
+
draft your talk proposal. Use this if you've ever meant to submit a talk
|
|
7
|
+
and missed the CFP because you found out a week too late.
|
|
8
|
+
category: learning
|
|
9
|
+
tags: [learning, conference, cfp, career]
|
|
10
|
+
schedule: "0 9 * * 1"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: hybrid
|
|
13
|
+
command: >
|
|
14
|
+
today=$(date +%s);
|
|
15
|
+
deadline_ts=$(date -d "{{cfp_deadline}}" +%s 2>/dev/null || date -jf "%Y-%m-%d" "{{cfp_deadline}}" +%s);
|
|
16
|
+
days_left=$(( (deadline_ts - today) / 86400 ));
|
|
17
|
+
if [ "$days_left" -le "{{warn_days}}" ] && [ "$days_left" -ge 0 ]; then echo "WARNING: {{conference_name}} CFP closes in $days_left days ({{cfp_deadline}})"; exit 1;
|
|
18
|
+
else echo "OK: {{conference_name}} CFP closes in $days_left days"; fi
|
|
19
|
+
prompt: |
|
|
20
|
+
The CFP for {{conference_name}} closes on {{cfp_deadline}}. Compute days
|
|
21
|
+
remaining from today.
|
|
22
|
+
1. If within {{warn_days}} days, flag it clearly.
|
|
23
|
+
2. Help draft a talk proposal abstract based on {{topic_hint}} — title,
|
|
24
|
+
3-sentence abstract, and why it fits this conference's audience.
|
|
25
|
+
script_note: >
|
|
26
|
+
`command` only checks the deadline and warns. `prompt` also drafts a
|
|
27
|
+
talk proposal abstract, which needs an LLM.
|
|
28
|
+
variables:
|
|
29
|
+
conference_name:
|
|
30
|
+
default: "a conference"
|
|
31
|
+
description: Name of the conference.
|
|
32
|
+
cfp_deadline:
|
|
33
|
+
default: "2026-09-01"
|
|
34
|
+
description: CFP submission deadline (YYYY-MM-DD).
|
|
35
|
+
warn_days:
|
|
36
|
+
default: 14
|
|
37
|
+
description: Days before deadline to start warning.
|
|
38
|
+
topic_hint:
|
|
39
|
+
default: "a project or topic you've been working on"
|
|
40
|
+
description: What you'd want to talk about, for the draft abstract.
|
|
41
|
+
compatible_agents: [claude, codex, hermes, openclaw, generic]
|
|
42
|
+
notes: Manual cfp_deadline input — update per conference you're tracking.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
id: medication-refill-reminder
|
|
2
|
+
version: 1
|
|
3
|
+
name: Medication Refill Reminder
|
|
4
|
+
description: >
|
|
5
|
+
Reminds you to refill a medication before you run out, based on how many
|
|
6
|
+
days of supply you have left. Use this if you've ever run out of a
|
|
7
|
+
prescription over a weekend when the pharmacy's closed.
|
|
8
|
+
category: personal
|
|
9
|
+
tags: [health, medication, reminder]
|
|
10
|
+
schedule: "0 9 * * *"
|
|
11
|
+
timezone: "America/Los_Angeles"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
today=$(date +%s);
|
|
15
|
+
runout_ts=$(date -d "{{runout_date}}" +%s 2>/dev/null || date -jf "%Y-%m-%d" "{{runout_date}}" +%s);
|
|
16
|
+
days_left=$(( (runout_ts - today) / 86400 ));
|
|
17
|
+
if [ "$days_left" -le "{{warn_days}}" ]; then echo "WARNING: {{medication_name}} runs out in $days_left days — refill now"; exit 1;
|
|
18
|
+
else echo "OK: {{medication_name}} has $days_left days left"; fi
|
|
19
|
+
variables:
|
|
20
|
+
medication_name:
|
|
21
|
+
default: "your medication"
|
|
22
|
+
description: Name of the medication to track.
|
|
23
|
+
runout_date:
|
|
24
|
+
default: "2026-08-01"
|
|
25
|
+
description: Date the current supply runs out (YYYY-MM-DD).
|
|
26
|
+
warn_days:
|
|
27
|
+
default: 5
|
|
28
|
+
description: Days before running out to start warning.
|
|
29
|
+
compatible_agents: [generic, claude, codex]
|
|
30
|
+
notes: Manual runout_date input — update it each time you fill the prescription.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
id: calendar-double-booking-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: Calendar Double-Booking Check
|
|
4
|
+
description: >
|
|
5
|
+
Checks today's calendar for overlapping meetings and flags them. Use
|
|
6
|
+
this if you've ever accepted two invites for the same slot and only
|
|
7
|
+
noticed when both started ringing.
|
|
8
|
+
category: productivity
|
|
9
|
+
tags: [calendar, meetings, productivity]
|
|
10
|
+
schedule: "0 7 * * 1-5"
|
|
11
|
+
timezone: "America/Los_Angeles"
|
|
12
|
+
runner: agent-prompt
|
|
13
|
+
prompt: |
|
|
14
|
+
Check today's calendar for overlapping events.
|
|
15
|
+
1. List all meetings scheduled for today.
|
|
16
|
+
2. Flag any pair of events whose times overlap.
|
|
17
|
+
3. For each conflict, report both event names, times, and organizers so
|
|
18
|
+
it's obvious which one to decline or reschedule.
|
|
19
|
+
variables: {}
|
|
20
|
+
compatible_agents: [claude, codex, hermes, openclaw, generic]
|
|
21
|
+
notes: No generic script mode — calendar access is provider-specific (Google Calendar, Outlook, etc.) and typically needs an agent with calendar-tool access.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
id: stale-todo-sweep
|
|
2
|
+
version: 1
|
|
3
|
+
name: Stale Todo Sweep
|
|
4
|
+
description: >
|
|
5
|
+
Finds TODO/FIXME comments in your codebase that have sat untouched for a
|
|
6
|
+
long time, so you can decide whether to fix, ticket, or delete them. Use
|
|
7
|
+
this if TODO comments in this repo have basically become permanent decor.
|
|
8
|
+
category: productivity
|
|
9
|
+
tags: [todos, cleanup, code-hygiene]
|
|
10
|
+
schedule: "0 9 * * 1"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
grep -rn "TODO\|FIXME" {{search_dir}} --include="*.{{ext}}" 2>/dev/null | while IFS=: read -r file line rest; do
|
|
15
|
+
last_change=$(git -C {{search_dir}} log -1 --format=%ar -- "$file" 2>/dev/null);
|
|
16
|
+
echo "$file:$line last touched $last_change: $rest"
|
|
17
|
+
done
|
|
18
|
+
variables:
|
|
19
|
+
search_dir:
|
|
20
|
+
default: "."
|
|
21
|
+
description: Directory to search for TODO/FIXME comments.
|
|
22
|
+
ext:
|
|
23
|
+
default: "js"
|
|
24
|
+
description: File extension to search (single extension; run multiple copies for multiple languages).
|
|
25
|
+
compatible_agents: [generic, claude, codex]
|
|
26
|
+
notes: The "last touched" date reflects the file's last git change, not the specific TODO line — a big refactor nearby will reset the age even if the TODO itself is old.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
id: cve-watch
|
|
2
|
+
version: 1
|
|
3
|
+
name: CVE Watch
|
|
4
|
+
description: >
|
|
5
|
+
Checks for newly published CVEs affecting packages in your stack. Use
|
|
6
|
+
this if you want a heads-up on a critical vulnerability before it shows
|
|
7
|
+
up in a routine dependency audit days later.
|
|
8
|
+
category: security
|
|
9
|
+
tags: [security, cve, vulnerabilities]
|
|
10
|
+
schedule: "0 8 * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: agent-prompt
|
|
13
|
+
prompt: |
|
|
14
|
+
Check for new CVEs published in the last 24 hours affecting the
|
|
15
|
+
dependencies used in this project (see {{manifest_hint}}).
|
|
16
|
+
1. Pull the current dependency list (name + version) from the manifest.
|
|
17
|
+
2. Check a CVE/vulnerability source (NVD, GitHub Advisory Database, OSV)
|
|
18
|
+
for new entries matching those packages.
|
|
19
|
+
3. Report any matches with severity, and whether a patched version is
|
|
20
|
+
already available.
|
|
21
|
+
4. If nothing new, say so in one line.
|
|
22
|
+
variables:
|
|
23
|
+
manifest_hint:
|
|
24
|
+
default: "package.json / requirements.txt / go.mod"
|
|
25
|
+
description: Which dependency manifest(s) to read for this project.
|
|
26
|
+
compatible_agents: [claude, codex, hermes, openclaw, generic]
|
|
27
|
+
notes: No generic script mode — matching CVEs to an arbitrary manifest against a live advisory database needs an agent, not a fixed CLI call.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
id: iam-key-rotation-reminder
|
|
2
|
+
version: 1
|
|
3
|
+
name: IAM Key Rotation Reminder
|
|
4
|
+
description: >
|
|
5
|
+
Checks how old your IAM access keys are and flags any past your rotation
|
|
6
|
+
age. Use this if you've ever found a years-old access key still active
|
|
7
|
+
because nobody was tracking key age.
|
|
8
|
+
category: security
|
|
9
|
+
tags: [security, iam, aws, rotation]
|
|
10
|
+
schedule: "0 8 1 * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
today=$(date +%s);
|
|
15
|
+
aws iam list-users --query 'Users[].UserName' --output text | tr '\t' '\n' | while read -r user; do
|
|
16
|
+
aws iam list-access-keys --user-name "$user" --query 'AccessKeyMetadata[].[AccessKeyId,CreateDate]' --output text | while read -r key created; do
|
|
17
|
+
created_ts=$(date -d "$created" +%s 2>/dev/null || date -jf "%Y-%m-%dT%H:%M:%S" "${created%+*}" +%s 2>/dev/null);
|
|
18
|
+
age_days=$(( (today - created_ts) / 86400 ));
|
|
19
|
+
if [ "$age_days" -ge "{{max_age_days}}" ]; then echo "WARNING: key $key for user $user is $age_days days old"; fi;
|
|
20
|
+
done;
|
|
21
|
+
done
|
|
22
|
+
variables:
|
|
23
|
+
max_age_days:
|
|
24
|
+
default: 90
|
|
25
|
+
description: Key age in days before it's flagged for rotation.
|
|
26
|
+
compatible_agents: [generic, claude, codex]
|
|
27
|
+
notes: Requires AWS CLI with iam:ListUsers and iam:ListAccessKeys permissions.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
id: s3-public-bucket-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: S3 Public Bucket Check
|
|
4
|
+
description: >
|
|
5
|
+
Checks your S3 buckets for public access and flags any that are exposed.
|
|
6
|
+
Use this if a misconfigured bucket policy has ever quietly made private
|
|
7
|
+
data public.
|
|
8
|
+
category: security
|
|
9
|
+
tags: [security, s3, aws, exposure]
|
|
10
|
+
schedule: "0 6 * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
aws s3api list-buckets --query 'Buckets[].Name' --output text | tr '\t' '\n' | while read -r bucket; do
|
|
15
|
+
status=$(aws s3api get-public-access-block --bucket "$bucket" 2>/dev/null);
|
|
16
|
+
if [ -z "$status" ]; then echo "WARNING: $bucket has no public access block configured"; fi;
|
|
17
|
+
done
|
|
18
|
+
variables: {}
|
|
19
|
+
compatible_agents: [generic, claude, codex]
|
|
20
|
+
notes: Requires AWS CLI configured with credentials that can call s3api list-buckets and get-public-access-block.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
id: oncall-handoff-reminder
|
|
2
|
+
version: 1
|
|
3
|
+
name: On-call Handoff Reminder
|
|
4
|
+
description: >
|
|
5
|
+
Nudges outgoing and incoming on-call to sync before the shift changes.
|
|
6
|
+
Use this if a handoff has ever happened silently and the new on-call
|
|
7
|
+
found out about an open incident from a page instead of a briefing.
|
|
8
|
+
category: team
|
|
9
|
+
tags: [oncall, handoff, team]
|
|
10
|
+
schedule: "0 9 * * 1"
|
|
11
|
+
timezone: "America/Los_Angeles"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
echo "On-call handoff today: {{outgoing}} -> {{incoming}}. Sync on open incidents, recent alerts, and anything in-flight before {{handoff_time}}."
|
|
15
|
+
variables:
|
|
16
|
+
outgoing:
|
|
17
|
+
default: "outgoing on-call"
|
|
18
|
+
description: Name of the person finishing their on-call shift.
|
|
19
|
+
incoming:
|
|
20
|
+
default: "incoming on-call"
|
|
21
|
+
description: Name of the person starting their on-call shift.
|
|
22
|
+
handoff_time:
|
|
23
|
+
default: "10:00"
|
|
24
|
+
description: Time the handoff should be complete by.
|
|
25
|
+
compatible_agents: [generic, claude, codex]
|
|
26
|
+
notes: Static reminder text — plug in your actual rotation (e.g. pull outgoing/incoming from PagerDuty) if you want it dynamic.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
id: team-anniversary-reminder
|
|
2
|
+
version: 1
|
|
3
|
+
name: Team Anniversary Reminder
|
|
4
|
+
description: >
|
|
5
|
+
Reminds you about teammates' birthdays and work anniversaries coming up
|
|
6
|
+
this week. Use this if you've ever felt bad realizing a work anniversary
|
|
7
|
+
passed with zero acknowledgment.
|
|
8
|
+
category: team
|
|
9
|
+
tags: [team, birthdays, anniversaries]
|
|
10
|
+
schedule: "0 9 * * 1"
|
|
11
|
+
timezone: "America/Los_Angeles"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
today=$(date +%m-%d);
|
|
15
|
+
end=$(date -d "+7 days" +%m-%d 2>/dev/null || date -v+7d +%m-%d);
|
|
16
|
+
awk -F, -v today="$today" -v end="$end" '$2 >= today && $2 <= end {print "UPCOMING: " $1 " (" $3 ") on " $2}' {{roster_csv}}
|
|
17
|
+
variables:
|
|
18
|
+
roster_csv:
|
|
19
|
+
default: "team-dates.csv"
|
|
20
|
+
description: "CSV with columns: name,date(MM-DD),type(birthday/anniversary)."
|
|
21
|
+
compatible_agents: [generic, claude, codex]
|
|
22
|
+
notes: Simple string comparison on MM-DD, so it doesn't handle windows spanning year-end (Dec into Jan) correctly — fine for most weeks.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
id: frequent-flyer-miles-expiry
|
|
2
|
+
version: 1
|
|
3
|
+
name: Frequent Flyer Miles Expiry Check
|
|
4
|
+
description: >
|
|
5
|
+
Warns you before frequent flyer miles or points expire from inactivity.
|
|
6
|
+
Use this if you've ever lost a stash of miles just because you didn't
|
|
7
|
+
fly or transact on the account in time.
|
|
8
|
+
category: travel
|
|
9
|
+
tags: [travel, miles, points, loyalty]
|
|
10
|
+
schedule: "0 9 1 * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
today=$(date +%s);
|
|
15
|
+
expiry_ts=$(date -d "{{expiry_date}}" +%s 2>/dev/null || date -jf "%Y-%m-%d" "{{expiry_date}}" +%s);
|
|
16
|
+
days_left=$(( (expiry_ts - today) / 86400 ));
|
|
17
|
+
if [ "$days_left" -le "{{warn_days}}" ]; then echo "WARNING: {{program_name}} miles expire in $days_left days ({{expiry_date}})"; exit 1;
|
|
18
|
+
else echo "OK: {{program_name}} miles expire in $days_left days"; fi
|
|
19
|
+
variables:
|
|
20
|
+
program_name:
|
|
21
|
+
default: "your airline program"
|
|
22
|
+
description: Name of the loyalty program.
|
|
23
|
+
expiry_date:
|
|
24
|
+
default: "2027-01-01"
|
|
25
|
+
description: Date the miles/points are set to expire (YYYY-MM-DD).
|
|
26
|
+
warn_days:
|
|
27
|
+
default: 30
|
|
28
|
+
description: Days before expiry to start warning.
|
|
29
|
+
compatible_agents: [generic, claude, codex]
|
|
30
|
+
notes: Expiry date is a manual input since most loyalty programs don't expose it via a public API — update expiry_date after checking your account.
|