@wonsukchoi/crondex 0.6.0 → 0.7.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 (57) hide show
  1. package/README.md +9 -1
  2. package/bin/crondex.js +85 -0
  3. package/catalog.json +1335 -35
  4. package/jobs/construction/inspection-deadline-reminder.yaml +31 -0
  5. package/jobs/construction/permit-expiry-check.yaml +31 -0
  6. package/jobs/content/hreflang-audit.yaml +25 -0
  7. package/jobs/content/image-alt-text-audit.yaml +21 -0
  8. package/jobs/content/page-speed-regression-watch.yaml +26 -0
  9. package/jobs/creator/content-calendar-gap-check.yaml +31 -0
  10. package/jobs/creator/engagement-drop-watch.yaml +36 -0
  11. package/jobs/devops/cdn-cache-purge-reminder.yaml +27 -0
  12. package/jobs/devops/ci-build-time-regression-watch.yaml +35 -0
  13. package/jobs/devops/k8s-pod-restart-watch.yaml +26 -0
  14. package/jobs/devops/log-forwarding-health-check.yaml +32 -0
  15. package/jobs/devops/staging-prod-config-diff.yaml +32 -0
  16. package/jobs/education/assignment-grading-backlog-check.yaml +23 -0
  17. package/jobs/education/attendance-anomaly-check.yaml +33 -0
  18. package/jobs/events/rsvp-followup-reminder.yaml +30 -0
  19. package/jobs/events/vendor-payment-deadline-reminder.yaml +31 -0
  20. package/jobs/finance/payroll-run-reminder.yaml +27 -0
  21. package/jobs/finance/recurring-payment-failure-check.yaml +23 -0
  22. package/jobs/fleet/fuel-card-anomaly-check.yaml +37 -0
  23. package/jobs/fleet/vehicle-maintenance-due-check.yaml +36 -0
  24. package/jobs/hiring/candidate-followup-nudge.yaml +23 -0
  25. package/jobs/hiring/open-req-aging-check.yaml +31 -0
  26. package/jobs/home/warranty-expiry-reminder.yaml +31 -0
  27. package/jobs/hospitality/food-safety-temp-log-check.yaml +36 -0
  28. package/jobs/hospitality/reservation-noshow-check.yaml +20 -0
  29. package/jobs/inventory/inventory-count-discrepancy-check.yaml +38 -0
  30. package/jobs/inventory/low-stock-alert.yaml +20 -0
  31. package/jobs/investing/crypto-price-alert.yaml +33 -0
  32. package/jobs/investing/portfolio-rebalance-check.yaml +32 -0
  33. package/jobs/legal/contract-renewal-reminder.yaml +31 -0
  34. package/jobs/legal/trademark-renewal-reminder.yaml +30 -0
  35. package/jobs/logistics/customs-clearance-check.yaml +34 -0
  36. package/jobs/logistics/shipment-delay-watch.yaml +38 -0
  37. package/jobs/manufacturing/production-line-downtime-watch.yaml +34 -0
  38. package/jobs/manufacturing/quality-defect-rate-check.yaml +20 -0
  39. package/jobs/marketing/ad-spend-pacing-check.yaml +37 -0
  40. package/jobs/marketing/email-deliverability-check.yaml +37 -0
  41. package/jobs/nonprofit/grant-deadline-reminder.yaml +44 -0
  42. package/jobs/nonprofit/lapsed-donor-check.yaml +26 -0
  43. package/jobs/podcast/episode-publish-gap-check.yaml +29 -0
  44. package/jobs/podcast/sponsor-deliverable-tracker.yaml +31 -0
  45. package/jobs/productivity/timezone-meeting-conflict-check.yaml +31 -0
  46. package/jobs/realestate/lease-expiry-reminder.yaml +30 -0
  47. package/jobs/realestate/rental-vacancy-check.yaml +30 -0
  48. package/jobs/sales/lead-response-time-check.yaml +23 -0
  49. package/jobs/sales/stale-deal-nudge.yaml +35 -0
  50. package/jobs/security/2fa-enrollment-audit.yaml +24 -0
  51. package/jobs/security/dependabot-alert-digest.yaml +30 -0
  52. package/jobs/security/expiring-api-key-rotation.yaml +31 -0
  53. package/jobs/security/tls-cipher-weak-check.yaml +31 -0
  54. package/jobs/security/waf-rule-change-watch.yaml +38 -0
  55. package/jobs/support/csat-score-watch.yaml +32 -0
  56. package/jobs/support/ticket-backlog-aging-check.yaml +30 -0
  57. package/package.json +1 -1
@@ -0,0 +1,31 @@
1
+ id: timezone-meeting-conflict-check
2
+ version: 1
3
+ name: Timezone Meeting Conflict Check
4
+ description: >
5
+ Checks tomorrow's meetings against a remote teammate's working hours and
6
+ flags any that fall outside them. Use this if a meeting has ever gotten
7
+ scheduled at 11pm for someone across the world without anyone realizing.
8
+ category: productivity
9
+ tags: [calendar, timezone, meetings]
10
+ schedule: "0 16 * * *"
11
+ timezone: "America/Los_Angeles"
12
+ runner: agent-prompt
13
+ prompt: |
14
+ Check tomorrow's calendar for meetings that include {{teammate_name}}
15
+ (timezone {{teammate_timezone}}, working hours {{working_hours}}).
16
+ 1. Convert each meeting time to {{teammate_name}}'s local time.
17
+ 2. Flag any meeting that falls outside their stated working hours.
18
+ 3. Suggest an alternative time inside working hours for each flagged
19
+ meeting if the calendar shows open slots.
20
+ variables:
21
+ teammate_name:
22
+ default: "your remote teammate"
23
+ description: Name of the teammate to check meetings against.
24
+ teammate_timezone:
25
+ default: "Europe/Berlin"
26
+ description: IANA timezone for the teammate.
27
+ working_hours:
28
+ default: "09:00-18:00"
29
+ description: The teammate's normal working hours, local time.
30
+ compatible_agents: [claude, codex, hermes, openclaw, generic]
31
+ notes: No generic script mode — calendar access and timezone-aware conflict detection need an agent with calendar-tool access.
@@ -0,0 +1,30 @@
1
+ id: lease-expiry-reminder
2
+ version: 1
3
+ name: Lease Expiry Reminder
4
+ description: >
5
+ Warns you before a lease ends so there's time to renew, renegotiate, or
6
+ start looking. Use this if a lease has ever gone month-to-month, or
7
+ ended, without anyone noticing the date was coming.
8
+ category: realestate
9
+ tags: [realestate, lease, reminder]
10
+ schedule: "0 9 1 * *"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ today=$(date +%s);
15
+ end_ts=$(date -d "{{lease_end_date}}" +%s 2>/dev/null || date -jf "%Y-%m-%d" "{{lease_end_date}}" +%s);
16
+ days_left=$(( (end_ts - today) / 86400 ));
17
+ if [ "$days_left" -le "{{warn_days}}" ]; then echo "WARNING: lease for {{property_name}} ends in $days_left days ({{lease_end_date}})"; exit 1;
18
+ else echo "OK: lease for {{property_name}} ends in $days_left days"; fi
19
+ variables:
20
+ property_name:
21
+ default: "your unit"
22
+ description: Name/address of the leased property.
23
+ lease_end_date:
24
+ default: "2027-01-01"
25
+ description: Lease end date (YYYY-MM-DD).
26
+ warn_days:
27
+ default: 60
28
+ description: Days before end date to start warning.
29
+ compatible_agents: [generic, claude, codex]
30
+ notes: Manual lease_end_date input — run one copy per property/unit you're tracking.
@@ -0,0 +1,30 @@
1
+ id: rental-vacancy-check
2
+ version: 1
3
+ name: Rental Vacancy Check
4
+ description: >
5
+ Flags a rental listing that's been vacant longer than expected. Use this
6
+ if a unit has ever sat empty for months while everyone assumed someone
7
+ else was handling the listing.
8
+ category: realestate
9
+ tags: [realestate, vacancy, listings]
10
+ schedule: "0 9 * * 1"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ today=$(date +%s);
15
+ vacant_since_ts=$(date -d "{{vacant_since_date}}" +%s 2>/dev/null || date -jf "%Y-%m-%d" "{{vacant_since_date}}" +%s);
16
+ days_vacant=$(( (today - vacant_since_ts) / 86400 ));
17
+ if [ "$days_vacant" -ge "{{warn_days}}" ]; then echo "WARNING: {{property_name}} has been vacant $days_vacant days (since {{vacant_since_date}})"; exit 1;
18
+ else echo "OK: {{property_name}} vacant $days_vacant days"; fi
19
+ variables:
20
+ property_name:
21
+ default: "your unit"
22
+ description: Name/address of the vacant property.
23
+ vacant_since_date:
24
+ default: "2026-06-01"
25
+ description: Date the unit became vacant (YYYY-MM-DD).
26
+ warn_days:
27
+ default: 30
28
+ description: Days vacant before it's flagged.
29
+ compatible_agents: [generic, claude, codex]
30
+ notes: Manual vacant_since_date input — update it once the unit is leased, or when a new vacancy starts.
@@ -0,0 +1,23 @@
1
+ id: lead-response-time-check
2
+ version: 1
3
+ name: Lead Response Time Check
4
+ description: >
5
+ Flags new inbound leads that haven't gotten a first response within your
6
+ target window. Use this if you've ever lost a hot lead simply because
7
+ nobody replied fast enough.
8
+ category: sales
9
+ tags: [sales, leads, response-time]
10
+ schedule: "*/30 * * * *"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ psql "{{database_url}}" -t -c "select name, email, created_at from leads where first_response_at is null and created_at < now() - interval '{{max_response_minutes}} minutes';"
15
+ variables:
16
+ database_url:
17
+ default: "postgres://user:pass@host:5432/db"
18
+ description: Connection string for the leads database.
19
+ max_response_minutes:
20
+ default: 30
21
+ description: Minutes a lead can go without a first response before it's flagged.
22
+ compatible_agents: [generic, claude, codex]
23
+ notes: Assumes a `leads` table with `created_at` and `first_response_at` columns — adjust the query to your CRM's schema.
@@ -0,0 +1,35 @@
1
+ id: stale-deal-nudge
2
+ version: 1
3
+ name: Stale Deal Nudge
4
+ description: >
5
+ Finds open pipeline deals nobody's touched in a while. Use this if deals
6
+ have ever quietly died in "in progress" because follow-up only happens
7
+ when someone remembers.
8
+ category: sales
9
+ tags: [sales, pipeline, crm]
10
+ schedule: "0 8 * * 1-5"
11
+ timezone: "UTC"
12
+ runner: hybrid
13
+ command: >
14
+ psql "{{database_url}}" -t -c "select name, owner, last_activity_at from deals where stage not in ('closed_won','closed_lost') and last_activity_at < now() - interval '{{stale_days}} days';"
15
+ prompt: |
16
+ Find open deals in {{crm_hint}} with no activity in the last
17
+ {{stale_days}} days.
18
+ 1. List each deal with owner, stage, value, and days since last activity.
19
+ 2. Draft a short follow-up nudge message for the owner of each, prompting
20
+ next-step action (call, email, or mark as closed-lost).
21
+ script_note: >
22
+ `command` lists stale deals from Postgres with zero tokens. `prompt`
23
+ works with any CRM and also drafts the follow-up nudge per owner.
24
+ variables:
25
+ database_url:
26
+ default: "postgres://user:pass@host:5432/db"
27
+ description: Connection string for the CRM/deals database.
28
+ crm_hint:
29
+ default: "your CRM (Salesforce, HubSpot, Pipedrive)"
30
+ description: Name of the CRM in use, for agent-prompt mode.
31
+ stale_days:
32
+ default: 14
33
+ description: Days without activity before a deal counts as stale.
34
+ compatible_agents: [claude, codex, hermes, openclaw, generic]
35
+ notes: Script mode assumes a `deals` table with `stage`, `owner`, and `last_activity_at` columns — adjust the query to your schema.
@@ -0,0 +1,24 @@
1
+ id: 2fa-enrollment-audit
2
+ version: 1
3
+ name: 2FA Enrollment Audit
4
+ description: >
5
+ Checks which team members in your identity provider or GitHub org don't
6
+ have two-factor auth enabled. Use this if you've ever assumed everyone
7
+ had 2FA on until an incident review proved otherwise.
8
+ category: security
9
+ tags: [security, 2fa, access]
10
+ schedule: "0 9 1 * *"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ command -v gh >/dev/null 2>&1 || { echo "ERROR: gh CLI not installed"; exit 1; };
15
+ gh api "orgs/{{org}}/members?filter=2fa_disabled" --jq '.[].login' > /tmp/2fa-disabled.txt 2>/dev/null;
16
+ count=$(wc -l < /tmp/2fa-disabled.txt | tr -d ' ');
17
+ if [ "$count" -eq 0 ]; then echo "OK: all org members have 2FA enabled";
18
+ else echo "WARNING: $count member(s) without 2FA:"; cat /tmp/2fa-disabled.txt; fi
19
+ variables:
20
+ org:
21
+ default: "your-org"
22
+ description: GitHub organization login to audit.
23
+ compatible_agents: [generic, claude, codex]
24
+ notes: Requires gh CLI authenticated as an org owner/admin — the 2fa_disabled filter needs admin:org scope.
@@ -0,0 +1,30 @@
1
+ id: dependabot-alert-digest
2
+ version: 1
3
+ name: Dependabot Alert Digest
4
+ description: >
5
+ Rolls up open Dependabot security alerts across a repo into one digest.
6
+ Use this if Dependabot alerts have ever piled up in a tab nobody checks
7
+ instead of getting triaged as they come in.
8
+ category: security
9
+ tags: [security, dependabot, github]
10
+ schedule: "0 8 * * 1"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ command -v gh >/dev/null 2>&1 || { echo "ERROR: gh CLI not installed"; exit 1; };
15
+ count=$(gh api "repos/{{owner}}/{{repo}}/dependabot/alerts?state=open" --jq 'length' 2>/dev/null);
16
+ if [ -z "$count" ]; then echo "ERROR: could not fetch Dependabot alerts (check gh auth and repo access)"; exit 1;
17
+ elif [ "$count" -eq 0 ]; then echo "OK: no open Dependabot alerts";
18
+ else
19
+ echo "$count open Dependabot alert(s):";
20
+ gh api "repos/{{owner}}/{{repo}}/dependabot/alerts?state=open" --jq '.[] | "- " + .security_advisory.severity + ": " + .security_advisory.summary';
21
+ fi
22
+ variables:
23
+ owner:
24
+ default: "your-org"
25
+ description: GitHub repo owner/org.
26
+ repo:
27
+ default: "your-repo"
28
+ description: GitHub repo name.
29
+ compatible_agents: [generic, claude, codex]
30
+ notes: Requires gh CLI authenticated with a token that has security_events read access on the repo.
@@ -0,0 +1,31 @@
1
+ id: expiring-api-key-rotation
2
+ version: 1
3
+ name: Expiring API Key Rotation Reminder
4
+ description: >
5
+ Warns you before a third-party API key or token you're tracking expires.
6
+ Use this if an integration has ever gone down in production because a
7
+ key expired and nobody rotated it in time.
8
+ category: security
9
+ tags: [security, api-keys, rotation]
10
+ schedule: "0 8 * * *"
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: key \"" $1 "\" expires in " days_left " days (" $2 ")";
21
+ }
22
+ ' {{keys_csv}}
23
+ variables:
24
+ keys_csv:
25
+ default: "api-keys.csv"
26
+ description: "CSV with header row, columns: key_name,expiry_date(YYYY-MM-DD)."
27
+ warn_days:
28
+ default: 14
29
+ description: Days before expiry to start warning.
30
+ compatible_agents: [generic, claude, codex]
31
+ notes: Keep api-keys.csv updated manually as a lightweight registry — most providers don't expose expiry via a common API.
@@ -0,0 +1,31 @@
1
+ id: tls-cipher-weak-check
2
+ version: 1
3
+ name: Weak TLS Cipher/Protocol Check
4
+ description: >
5
+ Checks a host for weak TLS protocol versions or ciphers still enabled.
6
+ Use this if a legacy protocol has ever stayed enabled for "just in
7
+ case" long after every client that needed it was gone.
8
+ category: security
9
+ tags: [security, tls, ciphers]
10
+ schedule: "0 6 * * 1"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ command -v openssl >/dev/null 2>&1 || { echo "ERROR: openssl not installed"; exit 1; };
15
+ weak_found=0;
16
+ for proto in ssl3 tls1 tls1_1; do
17
+ if openssl s_client -connect {{host}}:{{port}} -$proto </dev/null 2>/dev/null | grep -q "Cipher is"; then
18
+ echo "WARNING: {{host}}:{{port}} accepts $proto";
19
+ weak_found=1;
20
+ fi;
21
+ done;
22
+ if [ "$weak_found" -eq 0 ]; then echo "OK: {{host}}:{{port}} does not accept SSLv3/TLS1.0/TLS1.1"; else exit 1; fi
23
+ variables:
24
+ host:
25
+ default: "example.com"
26
+ description: Hostname to check.
27
+ port:
28
+ default: 443
29
+ description: Port to check.
30
+ compatible_agents: [generic, claude, codex]
31
+ notes: Requires an openssl build with legacy protocol support compiled in to actually detect them; a modern openssl that's dropped them entirely will just fail to connect either way (still safe).
@@ -0,0 +1,38 @@
1
+ id: waf-rule-change-watch
2
+ version: 1
3
+ name: WAF Rule Change Watch
4
+ description: >
5
+ Diffs your current WAF rules against a saved baseline and flags drift.
6
+ Use this if a WAF rule has ever been loosened "just for testing" and
7
+ never put back.
8
+ category: security
9
+ tags: [security, waf, drift]
10
+ schedule: "0 6 * * *"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ command -v aws >/dev/null 2>&1 || { echo "ERROR: aws CLI not installed"; exit 1; };
15
+ aws wafv2 get-web-acl --name {{web_acl_name}} --scope {{scope}} --id {{web_acl_id}} --query 'WebACL.Rules' --output json > /tmp/waf-current.json 2>/dev/null;
16
+ if [ ! -s /tmp/waf-current.json ]; then echo "ERROR: could not fetch WAF rules for {{web_acl_name}}"; exit 1; fi;
17
+ if [ -f {{baseline_file}} ]; then
18
+ if diff -q {{baseline_file}} /tmp/waf-current.json >/dev/null; then echo "OK: WAF rules match baseline";
19
+ else echo "DRIFT DETECTED in {{web_acl_name}} rules:"; diff {{baseline_file}} /tmp/waf-current.json; exit 1; fi
20
+ else
21
+ echo "no baseline at {{baseline_file}} yet — copying current rules as the new baseline";
22
+ cp /tmp/waf-current.json {{baseline_file}};
23
+ fi
24
+ variables:
25
+ web_acl_name:
26
+ default: "your-web-acl"
27
+ description: Name of the AWS WAFv2 Web ACL to check.
28
+ web_acl_id:
29
+ default: "your-web-acl-id"
30
+ description: ID of the Web ACL.
31
+ scope:
32
+ default: "REGIONAL"
33
+ description: WAF scope, REGIONAL or CLOUDFRONT.
34
+ baseline_file:
35
+ default: "waf-baseline.json"
36
+ description: Path to the saved baseline rules file to diff against.
37
+ compatible_agents: [generic, claude, codex]
38
+ notes: Written for AWS WAFv2 — adapt the fetch command for Cloudflare, Azure Front Door, or other WAF providers.
@@ -0,0 +1,32 @@
1
+ id: csat-score-watch
2
+ version: 1
3
+ name: CSAT Score Watch
4
+ description: >
5
+ Checks your recent customer satisfaction score and flags it if it drops
6
+ below your target. Use this if CSAT only gets looked at once a quarter,
7
+ by which point a bad week is old news.
8
+ category: support
9
+ tags: [support, csat, customer-satisfaction]
10
+ schedule: "0 9 * * 1"
11
+ timezone: "UTC"
12
+ runner: agent-prompt
13
+ prompt: |
14
+ Check the CSAT (or equivalent satisfaction) score for the last
15
+ {{lookback_days}} days from {{csat_source_hint}}.
16
+ 1. Compare it to the {{target_score}} target.
17
+ 2. If below target, pull 2-3 representative low-scoring responses to
18
+ show what's driving it.
19
+ 3. Report the score, trend vs. the prior period, and the drivers if
20
+ applicable, in under 150 words.
21
+ variables:
22
+ csat_source_hint:
23
+ default: "helpdesk tool (Zendesk, Intercom, etc.)"
24
+ description: Where CSAT/satisfaction survey data lives.
25
+ lookback_days:
26
+ default: 7
27
+ description: Rolling window to evaluate.
28
+ target_score:
29
+ default: 90
30
+ description: Target CSAT score (percent or your tool's native scale).
31
+ compatible_agents: [claude, codex, hermes, openclaw, generic]
32
+ notes: No generic script mode — CSAT scoring and survey formats vary too much by helpdesk tool for a fixed command.
@@ -0,0 +1,30 @@
1
+ id: ticket-backlog-aging-check
2
+ version: 1
3
+ name: Support Ticket Backlog Aging Check
4
+ description: >
5
+ Checks how many open support tickets have sat unanswered past your SLA
6
+ window. Use this if tickets have ever quietly aged past their SLA
7
+ because the backlog view wasn't checked that day.
8
+ category: support
9
+ tags: [support, sla, tickets]
10
+ schedule: "0 */4 * * *"
11
+ timezone: "UTC"
12
+ runner: shell
13
+ command: >
14
+ command -v curl >/dev/null 2>&1 || { echo "ERROR: curl not installed"; exit 1; };
15
+ count=$(curl -s -H "Authorization: Bearer {{api_token}}" "{{api_url}}" | grep -o '"status":"open"' | wc -l | tr -d ' ');
16
+ if [ -z "$count" ] || [ "$count" -eq 0 ]; then echo "OK: no aging open tickets found (or endpoint returned nothing)"; exit 0;
17
+ elif [ "$count" -ge "{{threshold}}" ]; then echo "WARNING: $count open tickets past SLA at {{api_url}}"; exit 1;
18
+ else echo "OK: $count open tickets past SLA (under threshold {{threshold}})"; fi
19
+ variables:
20
+ api_url:
21
+ default: "https://api.example-helpdesk.com/tickets?status=open&age_gt_hours=24"
22
+ description: Helpdesk API endpoint pre-filtered to tickets past your SLA age.
23
+ api_token:
24
+ default: "your-api-token"
25
+ description: Bearer token for the helpdesk API.
26
+ threshold:
27
+ default: 5
28
+ description: Number of aging open tickets that triggers a warning.
29
+ compatible_agents: [generic, claude, codex]
30
+ notes: Generic REST pattern — point api_url at your helpdesk's (Zendesk, Intercom, Freshdesk) filtered ticket search endpoint; adjust the grep pattern to match its response shape.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wonsukchoi/crondex",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "A public directory of pre-made, agent-editable cron jobs.",
5
5
  "type": "module",
6
6
  "license": "MIT",