@wonsukchoi/crondex 0.6.0 → 0.8.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.
Files changed (75) hide show
  1. package/README.md +52 -128
  2. package/bin/crondex.js +85 -0
  3. package/catalog.json +1891 -153
  4. package/jobs/construction/change-order-approval-reminder.yaml +31 -0
  5. package/jobs/construction/inspection-deadline-reminder.yaml +31 -0
  6. package/jobs/construction/permit-expiry-check.yaml +31 -0
  7. package/jobs/content/hreflang-audit.yaml +25 -0
  8. package/jobs/content/image-alt-text-audit.yaml +21 -0
  9. package/jobs/content/page-speed-regression-watch.yaml +26 -0
  10. package/jobs/creator/content-calendar-gap-check.yaml +31 -0
  11. package/jobs/creator/crosspost-lag-check.yaml +35 -0
  12. package/jobs/creator/engagement-drop-watch.yaml +36 -0
  13. package/jobs/devops/cdn-cache-purge-reminder.yaml +27 -0
  14. package/jobs/devops/ci-build-time-regression-watch.yaml +35 -0
  15. package/jobs/devops/k8s-pod-restart-watch.yaml +26 -0
  16. package/jobs/devops/log-forwarding-health-check.yaml +32 -0
  17. package/jobs/devops/staging-prod-config-diff.yaml +32 -0
  18. package/jobs/education/assignment-grading-backlog-check.yaml +23 -0
  19. package/jobs/education/attendance-anomaly-check.yaml +33 -0
  20. package/jobs/education/report-card-deadline-reminder.yaml +27 -0
  21. package/jobs/events/event-budget-overrun-check.yaml +31 -0
  22. package/jobs/events/rsvp-followup-reminder.yaml +30 -0
  23. package/jobs/events/vendor-payment-deadline-reminder.yaml +31 -0
  24. package/jobs/finance/payroll-run-reminder.yaml +27 -0
  25. package/jobs/finance/recurring-payment-failure-check.yaml +23 -0
  26. package/jobs/fleet/fuel-card-anomaly-check.yaml +37 -0
  27. package/jobs/fleet/vehicle-maintenance-due-check.yaml +36 -0
  28. package/jobs/fleet/vehicle-registration-expiry-check.yaml +31 -0
  29. package/jobs/hiring/candidate-followup-nudge.yaml +23 -0
  30. package/jobs/hiring/offer-expiry-reminder.yaml +31 -0
  31. package/jobs/hiring/open-req-aging-check.yaml +31 -0
  32. package/jobs/home/warranty-expiry-reminder.yaml +31 -0
  33. package/jobs/hospitality/food-safety-temp-log-check.yaml +36 -0
  34. package/jobs/hospitality/health-inspection-due-reminder.yaml +32 -0
  35. package/jobs/hospitality/reservation-noshow-check.yaml +20 -0
  36. package/jobs/inventory/expiring-perishable-stock-check.yaml +24 -0
  37. package/jobs/inventory/inventory-count-discrepancy-check.yaml +38 -0
  38. package/jobs/inventory/low-stock-alert.yaml +20 -0
  39. package/jobs/investing/crypto-price-alert.yaml +33 -0
  40. package/jobs/investing/dividend-payment-tracker.yaml +34 -0
  41. package/jobs/investing/portfolio-rebalance-check.yaml +32 -0
  42. package/jobs/legal/contract-renewal-reminder.yaml +31 -0
  43. package/jobs/legal/nda-expiry-check.yaml +31 -0
  44. package/jobs/legal/trademark-renewal-reminder.yaml +30 -0
  45. package/jobs/logistics/customs-clearance-check.yaml +34 -0
  46. package/jobs/logistics/freight-rate-spike-watch.yaml +38 -0
  47. package/jobs/logistics/shipment-delay-watch.yaml +38 -0
  48. package/jobs/manufacturing/preventive-maintenance-due-check.yaml +31 -0
  49. package/jobs/manufacturing/production-line-downtime-watch.yaml +34 -0
  50. package/jobs/manufacturing/quality-defect-rate-check.yaml +20 -0
  51. package/jobs/marketing/ad-spend-pacing-check.yaml +37 -0
  52. package/jobs/marketing/email-deliverability-check.yaml +37 -0
  53. package/jobs/marketing/seo-rank-drop-watch.yaml +38 -0
  54. package/jobs/nonprofit/grant-deadline-reminder.yaml +44 -0
  55. package/jobs/nonprofit/lapsed-donor-check.yaml +26 -0
  56. package/jobs/nonprofit/volunteer-hours-shortfall-check.yaml +30 -0
  57. package/jobs/podcast/episode-publish-gap-check.yaml +29 -0
  58. package/jobs/podcast/guest-followup-reminder.yaml +31 -0
  59. package/jobs/podcast/sponsor-deliverable-tracker.yaml +31 -0
  60. package/jobs/productivity/timezone-meeting-conflict-check.yaml +31 -0
  61. package/jobs/realestate/lease-expiry-reminder.yaml +30 -0
  62. package/jobs/realestate/rent-payment-late-check.yaml +23 -0
  63. package/jobs/realestate/rental-vacancy-check.yaml +30 -0
  64. package/jobs/sales/lead-response-time-check.yaml +23 -0
  65. package/jobs/sales/quota-attainment-check.yaml +33 -0
  66. package/jobs/sales/stale-deal-nudge.yaml +35 -0
  67. package/jobs/security/2fa-enrollment-audit.yaml +24 -0
  68. package/jobs/security/dependabot-alert-digest.yaml +30 -0
  69. package/jobs/security/expiring-api-key-rotation.yaml +31 -0
  70. package/jobs/security/tls-cipher-weak-check.yaml +31 -0
  71. package/jobs/security/waf-rule-change-watch.yaml +38 -0
  72. package/jobs/support/csat-score-watch.yaml +32 -0
  73. package/jobs/support/sla-breach-warning.yaml +31 -0
  74. package/jobs/support/ticket-backlog-aging-check.yaml +30 -0
  75. package/package.json +1 -1
@@ -0,0 +1,31 @@
1
+ id: change-order-approval-reminder
2
+ version: 1
3
+ name: Change Order Approval Reminder
4
+ description: >
5
+ Flags change orders that have been waiting on client sign-off too long.
6
+ Use this if work has ever stalled, or gone ahead unapproved, because a
7
+ change order sat in someone's inbox for weeks.
8
+ category: construction
9
+ tags: [construction, change-orders, approvals]
10
+ schedule: "0 8 * * 1-5"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ today=$(date +%s);
15
+ awk -F, -v today="$today" -v warn={{stale_days}} '
16
+ NR>1 && $3 == "pending" {
17
+ cmd="date -d \"" $2 "\" +%s 2>/dev/null || date -jf \"%Y-%m-%d\" \"" $2 "\" +%s";
18
+ cmd | getline sent_ts; close(cmd);
19
+ days_waiting = int((today - sent_ts) / 86400);
20
+ if (days_waiting >= warn) print "WARNING: change order \"" $1 "\" pending " days_waiting " days (sent " $2 ")";
21
+ }
22
+ ' {{change_orders_csv}}
23
+ variables:
24
+ change_orders_csv:
25
+ default: "change-orders.csv"
26
+ description: "CSV with header row, columns: description,sent_date(YYYY-MM-DD),status(pending/approved/rejected)."
27
+ stale_days:
28
+ default: 5
29
+ description: Days pending before it's flagged for follow-up.
30
+ compatible_agents: [generic, claude, codex]
31
+ notes: Keep change-orders.csv updated as change orders go out and come back signed.
@@ -0,0 +1,31 @@
1
+ id: inspection-deadline-reminder
2
+ version: 1
3
+ name: Inspection Deadline Reminder
4
+ description: >
5
+ Warns you before a scheduled inspection date, so the site is actually
6
+ ready. Use this if an inspector has ever shown up to a site that wasn't
7
+ prepped because the date snuck up on the crew.
8
+ category: construction
9
+ tags: [construction, inspection, scheduling]
10
+ schedule: "0 7 * * *"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ today=$(date +%s);
15
+ awk -F, -v today="$today" -v warn={{warn_days}} '
16
+ NR>1 {
17
+ cmd="date -d \"" $2 "\" +%s 2>/dev/null || date -jf \"%Y-%m-%d\" \"" $2 "\" +%s";
18
+ cmd | getline insp_ts; close(cmd);
19
+ days_left = int((insp_ts - today) / 86400);
20
+ if (days_left <= warn && days_left >= 0) print "WARNING: " $1 " inspection in " days_left " days (" $2 ")";
21
+ }
22
+ ' {{inspections_csv}}
23
+ variables:
24
+ inspections_csv:
25
+ default: "inspections.csv"
26
+ description: "CSV with header row, columns: site_name,inspection_date(YYYY-MM-DD)."
27
+ warn_days:
28
+ default: 3
29
+ description: Days before the inspection to start warning.
30
+ compatible_agents: [generic, claude, codex]
31
+ notes: Keep inspections.csv updated as inspections get scheduled with the local authority.
@@ -0,0 +1,31 @@
1
+ id: permit-expiry-check
2
+ version: 1
3
+ name: Building Permit Expiry Check
4
+ description: >
5
+ Warns you before a building permit expires so work doesn't get caught
6
+ without valid coverage. Use this if a permit has ever lapsed mid-project
7
+ and forced a costly re-inspection or re-application.
8
+ category: construction
9
+ tags: [construction, permits, compliance]
10
+ schedule: "0 8 * * 1"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ today=$(date +%s);
15
+ awk -F, -v today="$today" -v warn={{warn_days}} '
16
+ NR>1 {
17
+ cmd="date -d \"" $2 "\" +%s 2>/dev/null || date -jf \"%Y-%m-%d\" \"" $2 "\" +%s";
18
+ cmd | getline exp_ts; close(cmd);
19
+ days_left = int((exp_ts - today) / 86400);
20
+ if (days_left <= warn) print "WARNING: permit \"" $1 "\" expires in " days_left " days (" $2 ")";
21
+ }
22
+ ' {{permits_csv}}
23
+ variables:
24
+ permits_csv:
25
+ default: "permits.csv"
26
+ description: "CSV with header row, columns: permit_name,expiry_date(YYYY-MM-DD)."
27
+ warn_days:
28
+ default: 30
29
+ description: Days before expiry to start warning.
30
+ compatible_agents: [generic, claude, codex]
31
+ notes: Keep permits.csv updated per project/site — one row per active permit.
@@ -0,0 +1,25 @@
1
+ id: hreflang-audit
2
+ version: 1
3
+ name: Hreflang Audit
4
+ description: >
5
+ Checks a page's hreflang tags for missing reciprocal links or obviously
6
+ wrong language/region codes. Use this if a hreflang mistake has ever
7
+ quietly sent the wrong country's visitors to the wrong language version.
8
+ category: content
9
+ tags: [seo, hreflang, international]
10
+ schedule: "0 7 * * 1"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ tags=$(curl -s {{page_url}} | grep -o '<link[^>]*rel=["'"'"']alternate["'"'"'][^>]*hreflang=["'"'"'][^"'"'"']*["'"'"'][^>]*>');
15
+ if [ -z "$tags" ]; then echo "WARNING: no hreflang tags found on {{page_url}}"; exit 1; fi;
16
+ echo "$tags" | grep -o 'hreflang=["'"'"'][^"'"'"']*' | sed 's/hreflang=["'"'"']//' | while read -r code; do
17
+ echo "$code" | grep -qE '^[a-z]{2}(-[A-Z]{2})?$|^x-default$' || echo "WARNING: suspicious hreflang code \"$code\" on {{page_url}}";
18
+ done;
19
+ echo "OK: found $(echo "$tags" | wc -l | tr -d ' ') hreflang tag(s) — verify reciprocal links manually"
20
+ variables:
21
+ page_url:
22
+ default: "https://example.com"
23
+ description: URL of the page to check.
24
+ compatible_agents: [generic, claude, codex]
25
+ notes: Flags malformed language/region codes and missing tags on this page only — checking reciprocal hreflang links across the whole site needs crawling every listed URL, which this job doesn't do.
@@ -0,0 +1,21 @@
1
+ id: image-alt-text-audit
2
+ version: 1
3
+ name: Image Alt Text Audit
4
+ description: >
5
+ Checks a page for images missing alt text. Use this if images have ever
6
+ shipped without alt text because nobody double-checked before merging.
7
+ category: content
8
+ tags: [seo, accessibility, images]
9
+ schedule: "0 7 * * 1"
10
+ timezone: "UTC"
11
+ runner: shell
12
+ command: >
13
+ count=$(curl -s {{page_url}} | grep -o '<img[^>]*>' | grep -cv 'alt=');
14
+ if [ "$count" -gt 0 ]; then echo "WARNING: $count image(s) missing alt text on {{page_url}}"; exit 1;
15
+ else echo "OK: all images on {{page_url}} have alt text"; fi
16
+ variables:
17
+ page_url:
18
+ default: "https://example.com"
19
+ description: URL of the page to check.
20
+ compatible_agents: [generic, claude, codex]
21
+ notes: Flags images with no alt attribute at all — doesn't judge whether existing alt text is actually descriptive.
@@ -0,0 +1,26 @@
1
+ id: page-speed-regression-watch
2
+ version: 1
3
+ name: Page Speed Regression Watch
4
+ description: >
5
+ Checks a page's load time against a baseline and flags a real
6
+ regression. Use this if a page has ever gotten slowly, silently slower
7
+ release after release until it was a real problem.
8
+ category: content
9
+ tags: [performance, seo, monitoring]
10
+ schedule: "0 6 * * *"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ time_total=$(curl -s -o /dev/null -w '%{time_total}' {{page_url}});
15
+ if awk "BEGIN{exit !($time_total > {{threshold_seconds}})}"; then
16
+ echo "WARNING: {{page_url}} took ${time_total}s to load (threshold {{threshold_seconds}}s)"; exit 1;
17
+ else echo "OK: {{page_url}} loaded in ${time_total}s"; fi
18
+ variables:
19
+ page_url:
20
+ default: "https://example.com"
21
+ description: URL of the page to check.
22
+ threshold_seconds:
23
+ default: 3
24
+ description: Load time in seconds beyond which to warn.
25
+ compatible_agents: [generic, claude, codex]
26
+ notes: Measures raw TTFB-through-download time via curl, not real browser rendering — use a synthetic monitoring tool for full Core Web Vitals.
@@ -0,0 +1,31 @@
1
+ id: content-calendar-gap-check
2
+ version: 1
3
+ name: Content Calendar Gap Check
4
+ description: >
5
+ Checks that you have something scheduled to post in the next few days.
6
+ Use this if your publishing cadence has ever quietly broken because
7
+ nothing was queued and nobody noticed until the gap already showed.
8
+ category: creator
9
+ tags: [content, calendar, publishing]
10
+ schedule: "0 9 * * 1,4"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ today=$(date +%s);
15
+ cutoff=$(( today + {{lookahead_days}} * 86400 ));
16
+ next_ts=$(awk -F, 'NR>1 {
17
+ cmd="date -d \"" $1 "\" +%s 2>/dev/null || date -jf \"%Y-%m-%d\" \"" $1 "\" +%s";
18
+ cmd | getline ts; close(cmd);
19
+ if (ts >= "'"$today"'") { print ts; exit }
20
+ }' {{schedule_csv}});
21
+ if [ -z "$next_ts" ] || [ "$next_ts" -gt "$cutoff" ]; then echo "WARNING: no post scheduled in the next {{lookahead_days}} days"; exit 1;
22
+ else echo "OK: next post is scheduled within {{lookahead_days}} days"; fi
23
+ variables:
24
+ schedule_csv:
25
+ default: "content-calendar.csv"
26
+ description: "CSV with header row, columns: publish_date(YYYY-MM-DD),title,platform."
27
+ lookahead_days:
28
+ default: 3
29
+ description: Days ahead that must have at least one scheduled post.
30
+ compatible_agents: [generic, claude, codex]
31
+ notes: Reads a plain CSV export of your content calendar — point schedule_csv at wherever your planning tool exports to.
@@ -0,0 +1,35 @@
1
+ id: crosspost-lag-check
2
+ version: 1
3
+ name: Crosspost Lag Check
4
+ description: >
5
+ Checks that content published on your primary platform actually got
6
+ mirrored to your other channels. Use this if a video or post has ever
7
+ gone up on YouTube and just never made it to the other platforms because
8
+ crossposting was manual and someone forgot.
9
+ category: creator
10
+ tags: [content, crosspost, publishing]
11
+ schedule: "0 10 * * *"
12
+ timezone: "UTC"
13
+ runner: agent-prompt
14
+ prompt: |
15
+ Compare recent uploads on {{primary_platform}} against what's been
16
+ posted on {{secondary_platforms}} over the last {{lookback_days}} days.
17
+ 1. List content published on {{primary_platform}} with no matching post
18
+ on one or more of {{secondary_platforms}} within {{max_lag_days}}
19
+ days of the original.
20
+ 2. Report each gap with the platform(s) missing it.
21
+ variables:
22
+ primary_platform:
23
+ default: "YouTube"
24
+ description: Your main publishing platform.
25
+ secondary_platforms:
26
+ default: "Instagram, TikTok, X"
27
+ description: Comma-separated list of platforms content should also land on.
28
+ lookback_days:
29
+ default: 14
30
+ description: How far back to check for crossposting gaps.
31
+ max_lag_days:
32
+ default: 3
33
+ description: Days after the original post before a missing crosspost counts as a gap.
34
+ compatible_agents: [claude, codex, hermes, openclaw, generic]
35
+ notes: No generic script mode — checking multiple platform APIs and matching content across them needs an agent, not a fixed query.
@@ -0,0 +1,36 @@
1
+ id: engagement-drop-watch
2
+ version: 1
3
+ name: Engagement Drop Watch
4
+ description: >
5
+ Compares recent post engagement to your baseline and flags a real drop.
6
+ Use this if you've ever kept posting into a falling algorithm curve for
7
+ weeks before noticing the numbers were down.
8
+ category: creator
9
+ tags: [content, engagement, social]
10
+ schedule: "0 9 * * 1"
11
+ timezone: "UTC"
12
+ runner: agent-prompt
13
+ prompt: |
14
+ Check engagement (likes, comments, shares, views — whatever the
15
+ platform reports) for posts on {{platform_hint}} over the last
16
+ {{recent_days}} days.
17
+ 1. Compare average engagement rate to the prior {{baseline_days}}-day
18
+ baseline.
19
+ 2. Flag a drop of {{drop_threshold_pct}}% or more.
20
+ 3. If flagged, note anything that changed around the drop (posting time,
21
+ format, frequency) if it's visible from the data.
22
+ variables:
23
+ platform_hint:
24
+ default: "your primary platform (YouTube, Instagram, TikTok, etc.)"
25
+ description: Which platform's analytics to check.
26
+ recent_days:
27
+ default: 7
28
+ description: Recent window to evaluate.
29
+ baseline_days:
30
+ default: 30
31
+ description: Prior window used as the baseline for comparison.
32
+ drop_threshold_pct:
33
+ default: 25
34
+ description: Percent drop in engagement rate that counts as a real decline.
35
+ compatible_agents: [claude, codex, hermes, openclaw, generic]
36
+ notes: No generic script mode — platform analytics APIs vary widely and most need OAuth the agent may not have configured.
@@ -0,0 +1,27 @@
1
+ id: cdn-cache-purge-reminder
2
+ version: 1
3
+ name: CDN Cache Purge Reminder
4
+ description: >
5
+ Reminds you to purge the CDN cache after a deploy, and can trigger it
6
+ directly if you give it credentials. Use this if you've ever shipped a
7
+ fix and then spent an hour confused why users still saw the old version.
8
+ category: devops
9
+ tags: [cdn, cache, deploy]
10
+ schedule: "*/30 * * * *"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ if [ -z "{{deploy_marker_file}}" ] || [ ! -f "{{deploy_marker_file}}" ]; then echo "OK: no pending deploy marker found"; exit 0; fi;
15
+ echo "REMINDER: deploy marker found at {{deploy_marker_file}} — purge CDN cache for {{cdn_zone}} if not already done, then remove the marker.";
16
+ variables:
17
+ deploy_marker_file:
18
+ default: ".deploy-pending"
19
+ description: Path to a marker file your deploy script touches; job reminds until it's removed.
20
+ cdn_zone:
21
+ default: "your CDN zone/distribution"
22
+ description: Name of the CDN zone, for the reminder text.
23
+ compatible_agents: [generic, claude, codex]
24
+ notes: >
25
+ Deliberately doesn't call any CDN API directly since providers differ
26
+ widely (Cloudflare, Fastly, CloudFront) — have your deploy script touch
27
+ the marker file, and remove it once cache is purged.
@@ -0,0 +1,35 @@
1
+ id: ci-build-time-regression-watch
2
+ version: 1
3
+ name: CI Build Time Regression Watch
4
+ description: >
5
+ Compares recent CI build durations to a baseline and flags a real
6
+ slowdown. Use this if build times have ever crept up gradually until a
7
+ 30-second CI run became a 15-minute one.
8
+ category: devops
9
+ tags: [ci, performance, build-time]
10
+ schedule: "0 9 * * 1-5"
11
+ timezone: "UTC"
12
+ runner: agent-prompt
13
+ prompt: |
14
+ Check recent CI run durations for {{repo_hint}} over the last
15
+ {{recent_runs}} runs on the main branch.
16
+ 1. Compute the average duration and compare to the average of the prior
17
+ {{baseline_runs}} runs.
18
+ 2. Flag a regression of {{threshold_pct}}% or more.
19
+ 3. If flagged, note which stage/job grew the most, if that breakdown is
20
+ available.
21
+ variables:
22
+ repo_hint:
23
+ default: "this repo's CI (GitHub Actions, CircleCI, etc.)"
24
+ description: Which repo and CI provider to check.
25
+ recent_runs:
26
+ default: 10
27
+ description: Number of recent runs to average for the current period.
28
+ baseline_runs:
29
+ default: 30
30
+ description: Number of prior runs to use as the baseline.
31
+ threshold_pct:
32
+ default: 30
33
+ description: Percent increase in average duration that counts as a regression.
34
+ compatible_agents: [claude, codex, hermes, openclaw, generic]
35
+ notes: No generic script mode — CI provider APIs vary, and per-stage timing breakdowns need provider-specific parsing.
@@ -0,0 +1,26 @@
1
+ id: k8s-pod-restart-watch
2
+ version: 1
3
+ name: Kubernetes Pod Restart Watch
4
+ description: >
5
+ Checks for pods with a high restart count and flags them. Use this if a
6
+ crash-looping pod has ever burned through hours before anyone noticed
7
+ it wasn't actually staying up.
8
+ category: devops
9
+ tags: [kubernetes, pods, monitoring]
10
+ schedule: "*/15 * * * *"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ command -v kubectl >/dev/null 2>&1 || { echo "ERROR: kubectl not installed"; exit 1; };
15
+ kubectl get pods -n {{namespace}} --no-headers 2>/dev/null | awk -v threshold={{threshold}} '
16
+ { restarts=$4+0; if (restarts >= threshold) print "WARNING: pod " $1 " has " restarts " restarts" }
17
+ '
18
+ variables:
19
+ namespace:
20
+ default: "default"
21
+ description: Kubernetes namespace to check.
22
+ threshold:
23
+ default: 5
24
+ description: Restart count that triggers a warning.
25
+ compatible_agents: [generic, claude, codex]
26
+ notes: Requires kubectl configured with a context pointing at the cluster; emits nothing if no pod is over threshold.
@@ -0,0 +1,32 @@
1
+ id: log-forwarding-health-check
2
+ version: 1
3
+ name: Log Forwarding Health Check
4
+ description: >
5
+ Checks that logs are still actually arriving at your log aggregator.
6
+ Use this if a log shipper has ever silently died and nobody found out
7
+ until they needed logs that were never collected.
8
+ category: devops
9
+ tags: [logging, monitoring, observability]
10
+ schedule: "*/30 * * * *"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ last_ts=$(curl -s -H "Authorization: Bearer {{log_api_token}}" "{{log_query_api_url}}" | grep -o '"timestamp":"[^"]*"' | sort -r | head -n1 | cut -d'"' -f4);
15
+ if [ -z "$last_ts" ]; then echo "WARNING: no recent log entries found via {{log_query_api_url}}"; exit 1; fi;
16
+ last_epoch=$(date -d "$last_ts" +%s 2>/dev/null);
17
+ now_epoch=$(date +%s);
18
+ minutes_since=$(( (now_epoch - last_epoch) / 60 ));
19
+ if [ "$minutes_since" -ge "{{max_gap_minutes}}" ]; then echo "WARNING: no new logs in $minutes_since minutes (last at $last_ts)"; exit 1;
20
+ else echo "OK: most recent log entry $minutes_since minutes ago"; fi
21
+ variables:
22
+ log_query_api_url:
23
+ default: "https://api.example-logs.com/query?limit=1&sort=desc"
24
+ description: Log aggregator API endpoint returning at least the most recent entry's timestamp.
25
+ log_api_token:
26
+ default: "your-api-token"
27
+ description: API token for the log aggregator.
28
+ max_gap_minutes:
29
+ default: 15
30
+ description: Minutes without a new log entry before it's flagged.
31
+ compatible_agents: [generic, claude, codex]
32
+ notes: Generic REST pattern — point log_query_api_url at your aggregator's (Datadog, Splunk, ELK) most-recent-entry query; adjust field names to match its response shape.
@@ -0,0 +1,32 @@
1
+ id: staging-prod-config-diff
2
+ version: 1
3
+ name: Staging vs Production Config Diff
4
+ description: >
5
+ Diffs environment variable keys between staging and production and
6
+ flags mismatches. Use this if staging and prod have ever quietly
7
+ drifted apart until a deploy broke only in one of them.
8
+ category: devops
9
+ tags: [config, environments, drift]
10
+ schedule: "0 8 * * 1"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ staging_keys=$(cut -d= -f1 {{staging_env_file}} | grep -v '^#' | sort);
15
+ prod_keys=$(cut -d= -f1 {{prod_env_file}} | grep -v '^#' | sort);
16
+ only_staging=$(comm -23 <(echo "$staging_keys") <(echo "$prod_keys"));
17
+ only_prod=$(comm -13 <(echo "$staging_keys") <(echo "$prod_keys"));
18
+ if [ -n "$only_staging" ] || [ -n "$only_prod" ]; then
19
+ echo "DRIFT DETECTED:";
20
+ [ -n "$only_staging" ] && echo "only in staging: $only_staging";
21
+ [ -n "$only_prod" ] && echo "only in prod: $only_prod";
22
+ exit 1;
23
+ else echo "OK: staging and prod env keys match"; fi
24
+ variables:
25
+ staging_env_file:
26
+ default: ".env.staging"
27
+ description: Path to the staging environment file (keys only compared, not values).
28
+ prod_env_file:
29
+ default: ".env.production"
30
+ description: Path to the production environment file.
31
+ compatible_agents: [generic, claude, codex]
32
+ notes: Compares key names only, never values, so secrets are never read or logged.
@@ -0,0 +1,23 @@
1
+ id: assignment-grading-backlog-check
2
+ version: 1
3
+ name: Assignment Grading Backlog Check
4
+ description: >
5
+ Checks how many submitted assignments are still ungraded and flags it if
6
+ the backlog is growing. Use this if grading has ever piled up for weeks
7
+ until students started asking where their grades were.
8
+ category: education
9
+ tags: [education, grading, backlog]
10
+ schedule: "0 8 * * 1-5"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ psql "{{database_url}}" -t -c "select course, count(*) from submissions where graded_at is null and submitted_at < now() - interval '{{stale_days}} days' group by course;"
15
+ variables:
16
+ database_url:
17
+ default: "postgres://user:pass@host:5432/db"
18
+ description: Connection string for the LMS/gradebook database.
19
+ stale_days:
20
+ default: 3
21
+ description: Days a submission can sit ungraded before it's counted in the backlog.
22
+ compatible_agents: [generic, claude, codex]
23
+ notes: Assumes a `submissions` table with `graded_at` and `submitted_at` — adjust the query for your LMS's schema or export.
@@ -0,0 +1,33 @@
1
+ id: attendance-anomaly-check
2
+ version: 1
3
+ name: Attendance Anomaly Check
4
+ description: >
5
+ Flags students whose attendance has dropped sharply, before it becomes a
6
+ pattern nobody caught early. Use this if a student's attendance has ever
7
+ quietly fallen off and only got noticed at report-card time.
8
+ category: education
9
+ tags: [education, attendance, students]
10
+ schedule: "0 8 * * 1"
11
+ timezone: "UTC"
12
+ runner: agent-prompt
13
+ prompt: |
14
+ Review attendance records from {{sis_hint}} for the last
15
+ {{recent_weeks}} weeks.
16
+ 1. Compare each student's recent attendance rate to their prior
17
+ baseline for the term.
18
+ 2. Flag students with a drop of {{drop_threshold_pct}} percentage
19
+ points or more.
20
+ 3. Report flagged students with their recent and baseline rates, so
21
+ follow-up (counselor, parent contact) can be prioritized.
22
+ variables:
23
+ sis_hint:
24
+ default: "your student information system"
25
+ description: Where attendance data lives.
26
+ recent_weeks:
27
+ default: 2
28
+ description: Recent window to evaluate.
29
+ drop_threshold_pct:
30
+ default: 20
31
+ description: Percentage-point drop in attendance rate that counts as an anomaly.
32
+ compatible_agents: [claude, codex, hermes, openclaw, generic]
33
+ notes: No generic script mode — SIS platforms vary widely and most need OAuth or export access the agent may not have configured.
@@ -0,0 +1,27 @@
1
+ id: report-card-deadline-reminder
2
+ version: 1
3
+ name: Report Card Deadline Reminder
4
+ description: >
5
+ Warns you before the grade submission deadline for report cards. Use
6
+ this if grades have ever gone in late because the cutoff snuck up
7
+ during the last busy week of the term.
8
+ category: education
9
+ tags: [education, grading, deadlines]
10
+ schedule: "0 8 * * *"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ today=$(date +%s);
15
+ due_ts=$(date -d "{{grades_due_date}}" +%s 2>/dev/null || date -jf "%Y-%m-%d" "{{grades_due_date}}" +%s);
16
+ days_left=$(( (due_ts - today) / 86400 ));
17
+ if [ "$days_left" -le "{{warn_days}}" ] && [ "$days_left" -ge 0 ]; then echo "WARNING: grades due in $days_left days ({{grades_due_date}})"; exit 1;
18
+ else echo "OK: grades due in $days_left days"; fi
19
+ variables:
20
+ grades_due_date:
21
+ default: "2026-12-15"
22
+ description: Grade submission deadline for this term (YYYY-MM-DD).
23
+ warn_days:
24
+ default: 5
25
+ description: Days before the deadline to start warning.
26
+ compatible_agents: [generic, claude, codex]
27
+ notes: Manual grades_due_date input — update it each term based on the school's academic calendar.
@@ -0,0 +1,31 @@
1
+ id: event-budget-overrun-check
2
+ version: 1
3
+ name: Event Budget Overrun Check
4
+ description: >
5
+ Compares committed spend so far against the event budget and flags
6
+ overrun risk. Use this if an event has ever come in over budget because
7
+ nobody totaled up the vendor contracts until after the fact.
8
+ category: events
9
+ tags: [events, budget, planning]
10
+ schedule: "0 9 * * 1"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ spent=$(awk -F, 'NR>1 {sum+=$2} END {print sum+0}' {{expenses_csv}});
15
+ budget={{budget_usd}};
16
+ if awk "BEGIN{exit !($spent >= $budget * {{warn_pct}} / 100)}"; then
17
+ echo "WARNING: committed spend \$$spent has hit ${warn_pct:-{{warn_pct}}}% of \$$budget budget";
18
+ exit 1;
19
+ else echo "OK: committed spend \$$spent of \$$budget budget"; fi
20
+ variables:
21
+ expenses_csv:
22
+ default: "event-expenses.csv"
23
+ description: "CSV with header row, columns: line_item,amount."
24
+ budget_usd:
25
+ default: 10000
26
+ description: Total event budget in USD.
27
+ warn_pct:
28
+ default: 90
29
+ description: Percent of budget committed before it's flagged.
30
+ compatible_agents: [generic, claude, codex]
31
+ notes: Keep event-expenses.csv updated as vendor contracts and deposits are committed, not just when invoices arrive.
@@ -0,0 +1,30 @@
1
+ id: rsvp-followup-reminder
2
+ version: 1
3
+ name: RSVP Follow-up Reminder
4
+ description: >
5
+ Flags invitees who haven't RSVP'd as the event date gets close. Use this
6
+ if you've ever had to guess headcount because half the guest list never
7
+ replied and nobody chased them.
8
+ category: events
9
+ tags: [events, rsvp, planning]
10
+ schedule: "0 9 * * 1"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ today=$(date +%s);
15
+ event_ts=$(date -d "{{event_date}}" +%s 2>/dev/null || date -jf "%Y-%m-%d" "{{event_date}}" +%s);
16
+ days_left=$(( (event_ts - today) / 86400 ));
17
+ if [ "$days_left" -gt "{{warn_days}}" ]; then echo "OK: event is $days_left days out, no follow-up needed yet"; exit 0; fi;
18
+ awk -F, 'NR>1 && $2 == "pending" {print "PENDING RSVP: " $1}' {{guest_list_csv}}
19
+ variables:
20
+ event_date:
21
+ default: "2026-12-01"
22
+ description: Date of the event (YYYY-MM-DD).
23
+ warn_days:
24
+ default: 14
25
+ description: Days before the event to start flagging pending RSVPs.
26
+ guest_list_csv:
27
+ default: "guest-list.csv"
28
+ description: "CSV with header row, columns: name,rsvp_status(pending/yes/no)."
29
+ compatible_agents: [generic, claude, codex]
30
+ notes: Keep guest-list.csv updated as RSVPs come in, or export it from your invite tool before each run.
@@ -0,0 +1,31 @@
1
+ id: vendor-payment-deadline-reminder
2
+ version: 1
3
+ name: Event Vendor Payment Deadline Reminder
4
+ description: >
5
+ Warns you before a vendor deposit or balance payment for an event is
6
+ due. Use this if a vendor has ever threatened to cancel because a
7
+ payment deadline slipped past unnoticed.
8
+ category: events
9
+ tags: [events, vendors, payments]
10
+ schedule: "0 9 * * *"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ today=$(date +%s);
15
+ awk -F, -v today="$today" -v warn={{warn_days}} '
16
+ NR>1 {
17
+ cmd="date -d \"" $2 "\" +%s 2>/dev/null || date -jf \"%Y-%m-%d\" \"" $2 "\" +%s";
18
+ cmd | getline due_ts; close(cmd);
19
+ days_left = int((due_ts - today) / 86400);
20
+ if (days_left <= warn && days_left >= 0) print "WARNING: payment to \"" $1 "\" (" $3 ") due in " days_left " days (" $2 ")";
21
+ }
22
+ ' {{vendor_payments_csv}}
23
+ variables:
24
+ vendor_payments_csv:
25
+ default: "vendor-payments.csv"
26
+ description: "CSV with header row, columns: vendor_name,due_date(YYYY-MM-DD),amount."
27
+ warn_days:
28
+ default: 7
29
+ description: Days before due date to start warning.
30
+ compatible_agents: [generic, claude, codex]
31
+ notes: Keep vendor-payments.csv updated as contracts are signed — one row per deposit/balance milestone.
@@ -0,0 +1,27 @@
1
+ id: payroll-run-reminder
2
+ version: 1
3
+ name: Payroll Run Reminder
4
+ description: >
5
+ Warns you before the payroll submission deadline so employees actually
6
+ get paid on time. Use this if payroll has ever run late because the
7
+ submission cutoff snuck up during a busy week.
8
+ category: finance
9
+ tags: [finance, payroll, deadlines]
10
+ schedule: "0 9 * * *"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ today=$(date +%s);
15
+ cutoff_ts=$(date -d "{{next_cutoff_date}}" +%s 2>/dev/null || date -jf "%Y-%m-%d" "{{next_cutoff_date}}" +%s);
16
+ days_left=$(( (cutoff_ts - today) / 86400 ));
17
+ if [ "$days_left" -le "{{warn_days}}" ] && [ "$days_left" -ge 0 ]; then echo "WARNING: payroll submission cutoff in $days_left days ({{next_cutoff_date}})"; exit 1;
18
+ else echo "OK: payroll submission cutoff in $days_left days"; fi
19
+ variables:
20
+ next_cutoff_date:
21
+ default: "2026-08-01"
22
+ description: Next payroll submission cutoff date (YYYY-MM-DD).
23
+ warn_days:
24
+ default: 2
25
+ description: Days before the cutoff to start warning.
26
+ compatible_agents: [generic, claude, codex]
27
+ notes: Manual next_cutoff_date input — update it each pay cycle, or generate a recurring schedule externally if your payroll provider uses a fixed cadence.