@wonsukchoi/crondex 0.21.0 → 0.22.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 +16 -30
- package/catalog.json +2294 -26
- package/jobs/ecommerce/affiliate-commission-payout-check.yaml +38 -0
- package/jobs/ecommerce/back-in-stock-notification-backlog-check.yaml +30 -0
- package/jobs/ecommerce/bundle-component-stock-mismatch-check.yaml +37 -0
- package/jobs/ecommerce/chargeback-fraud-risk-order-review.yaml +43 -0
- package/jobs/ecommerce/competitor-price-watch.yaml +60 -0
- package/jobs/ecommerce/economic-nexus-threshold-check.yaml +43 -0
- package/jobs/ecommerce/failed-payment-dunning-check.yaml +35 -0
- package/jobs/ecommerce/marketplace-listing-sync-drift-check.yaml +48 -0
- package/jobs/ecommerce/product-feed-health-check.yaml +35 -0
- package/jobs/ecommerce/purchase-order-overdue-check.yaml +32 -0
- package/jobs/ecommerce/storefront-ssl-domain-expiry-check.yaml +46 -0
- package/jobs/ecommerce/vip-tier-reclassification-check.yaml +55 -0
- package/jobs/ecommerce/wishlist-abandonment-check.yaml +37 -0
- package/jobs/finance/accounts-payable-aging-check.yaml +40 -0
- package/jobs/finance/bank-statement-reconciliation-check.yaml +40 -0
- package/jobs/finance/budget-vs-actual-variance-report.yaml +38 -0
- package/jobs/finance/contractor-1099-threshold-tracker.yaml +43 -0
- package/jobs/finance/credit-utilization-watch.yaml +40 -0
- package/jobs/finance/duplicate-payment-detection.yaml +43 -0
- package/jobs/finance/expense-report-compliance-check.yaml +46 -0
- package/jobs/finance/late-fee-interest-risk-check.yaml +43 -0
- package/jobs/finance/loan-covenant-compliance-check.yaml +37 -0
- package/jobs/finance/month-end-close-checklist-tracker.yaml +39 -0
- package/jobs/finance/multi-account-cash-position-rollup.yaml +45 -0
- package/jobs/finance/petty-cash-float-reconciliation.yaml +43 -0
- package/jobs/finance/quarterly-estimated-tax-calculator.yaml +66 -0
- package/jobs/finance/vendor-early-pay-discount-tracker.yaml +45 -0
- package/jobs/healthcare/appointment-slot-utilization-check.yaml +56 -0
- package/jobs/healthcare/claims-denial-resubmission-check.yaml +43 -0
- package/jobs/healthcare/clinical-supply-low-stock-check.yaml +30 -0
- package/jobs/healthcare/controlled-substance-inventory-reconciliation.yaml +42 -0
- package/jobs/healthcare/hipaa-access-log-audit.yaml +74 -0
- package/jobs/healthcare/patient-balance-collections-aging-check.yaml +41 -0
- package/jobs/healthcare/patient-immunization-schedule-check.yaml +41 -0
- package/jobs/healthcare/patient-portal-message-backlog-check.yaml +39 -0
- package/jobs/healthcare/patient-satisfaction-survey-tracking.yaml +59 -0
- package/jobs/healthcare/prescription-refill-request-backlog-check.yaml +38 -0
- package/jobs/healthcare/prior-authorization-expiry-check.yaml +53 -0
- package/jobs/healthcare/staff-cme-credit-tracking.yaml +41 -0
- package/jobs/healthcare/telehealth-session-issue-check.yaml +51 -0
- package/jobs/hr/aca-fte-threshold-monitor.yaml +44 -0
- package/jobs/hr/cobra-notification-deadline-tracker.yaml +47 -0
- package/jobs/hr/compliance-training-completion-check.yaml +41 -0
- package/jobs/hr/eeo1-filing-deadline-reminder.yaml +37 -0
- package/jobs/hr/handbook-acknowledgment-tracking.yaml +34 -0
- package/jobs/hr/headcount-budget-variance-check.yaml +37 -0
- package/jobs/hr/leave-of-absence-return-tracker.yaml +42 -0
- package/jobs/hr/org-chart-manager-drift-check.yaml +40 -0
- package/jobs/hr/pay-equity-band-outlier-check.yaml +58 -0
- package/jobs/hr/pto-year-end-use-it-or-lose-it-check.yaml +49 -0
- package/jobs/hr/retirement-plan-enrollment-deadline-check.yaml +40 -0
- package/jobs/hr/workers-comp-claim-status-check.yaml +42 -0
- package/jobs/legal/conflict-of-interest-check-tracker.yaml +38 -0
- package/jobs/legal/corporate-minute-book-completeness-check.yaml +31 -0
- package/jobs/legal/data-privacy-request-deadline-tracker.yaml +61 -0
- package/jobs/legal/entity-authority-document-expiry-check.yaml +37 -0
- package/jobs/legal/legal-document-retention-purge-review.yaml +39 -0
- package/jobs/legal/litigation-hold-acknowledgment-tracker.yaml +40 -0
- package/jobs/legal/non-compete-expiry-tracker.yaml +37 -0
- package/jobs/legal/outside-counsel-invoice-budget-check.yaml +37 -0
- package/jobs/legal/settlement-payment-schedule-tracker.yaml +34 -0
- package/jobs/legal/timekeeper-billable-hours-compliance-check.yaml +39 -0
- package/jobs/legal/trademark-infringement-watch.yaml +43 -0
- package/jobs/legal/vendor-coi-expiry-tracker.yaml +37 -0
- package/jobs/realestate/capital-reserve-fund-threshold-check.yaml +32 -0
- package/jobs/realestate/eviction-notice-deadline-tracker.yaml +37 -0
- package/jobs/realestate/landlord-insurance-claim-status-check.yaml +35 -0
- package/jobs/realestate/lease-renewal-offer-window-check.yaml +35 -0
- package/jobs/realestate/maintenance-request-sla-check.yaml +39 -0
- package/jobs/realestate/move-in-move-out-inspection-tracker.yaml +35 -0
- package/jobs/realestate/rent-increase-notice-deadline-check.yaml +54 -0
- package/jobs/realestate/rent-roll-vacancy-loss-report.yaml +32 -0
- package/jobs/realestate/rental-license-renewal-check.yaml +35 -0
- package/jobs/realestate/security-deposit-return-deadline-check.yaml +38 -0
- package/jobs/realestate/tenant-application-review-backlog-check.yaml +35 -0
- package/jobs/realestate/tenant-renters-insurance-compliance-check.yaml +35 -0
- package/jobs/realestate/utility-billback-reconciliation-check.yaml +41 -0
- package/jobs/sales/champion-departure-watch.yaml +44 -0
- package/jobs/sales/closed-lost-reason-audit.yaml +42 -0
- package/jobs/sales/commission-payout-tracker.yaml +32 -0
- package/jobs/sales/contract-renewal-opportunity-tracker.yaml +28 -0
- package/jobs/sales/discount-approval-pending-check.yaml +31 -0
- package/jobs/sales/forecast-submission-compliance-check.yaml +42 -0
- package/jobs/sales/multi-year-renewal-escalation-tracker.yaml +31 -0
- package/jobs/sales/pipeline-hygiene-audit.yaml +26 -0
- package/jobs/sales/poc-trial-conversion-tracker.yaml +29 -0
- package/jobs/sales/referral-followup-tracker.yaml +40 -0
- package/jobs/sales/territory-coverage-gap-check.yaml +43 -0
- package/lib/duplicates-allowlist.js +5 -0
- package/package.json +2 -2
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
id: tenant-renters-insurance-compliance-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: Tenant Renters Insurance Compliance Check
|
|
4
|
+
description: >
|
|
5
|
+
Checks tenants required by their lease to carry renters insurance
|
|
6
|
+
against their certificate's expiration date and flags anyone lapsed or
|
|
7
|
+
about to lapse. Use this if a tenant's coverage has ever quietly
|
|
8
|
+
expired mid-lease, leaving the landlord exposed on a liability claim
|
|
9
|
+
the lease was supposed to cover.
|
|
10
|
+
category: realestate
|
|
11
|
+
tags: [realestate, renters-insurance, compliance, tenant]
|
|
12
|
+
schedule: "0 8 * * 1"
|
|
13
|
+
timezone: "UTC"
|
|
14
|
+
runner: shell
|
|
15
|
+
command: >
|
|
16
|
+
today=$(date +%s);
|
|
17
|
+
awk -F',' -v today="$today" -v warn="{{warn_days}}" '
|
|
18
|
+
NR==1 {next}
|
|
19
|
+
{
|
|
20
|
+
cmd="date -d \"" $3 "\" +%s 2>/dev/null || date -jf \"%Y-%m-%d\" \"" $3 "\" +%s";
|
|
21
|
+
cmd | getline exp_ts; close(cmd);
|
|
22
|
+
days_left = int((exp_ts - today) / 86400);
|
|
23
|
+
if (days_left < 0) printf "LAPSED: %s (unit %s) renters insurance expired %d day(s) ago\n", $1, $2, -days_left;
|
|
24
|
+
else if (days_left <= warn) printf "EXPIRING SOON: %s (unit %s) renters insurance expires in %d day(s)\n", $1, $2, days_left;
|
|
25
|
+
}
|
|
26
|
+
' "{{renters_coi_csv}}"
|
|
27
|
+
variables:
|
|
28
|
+
renters_coi_csv:
|
|
29
|
+
default: "./tenant-renters-insurance.csv"
|
|
30
|
+
description: "CSV with header row, columns: tenant_name,unit,coverage_expiration_date(YYYY-MM-DD)."
|
|
31
|
+
warn_days:
|
|
32
|
+
default: 14
|
|
33
|
+
description: Days before expiration to start warning.
|
|
34
|
+
compatible_agents: [generic, claude, codex]
|
|
35
|
+
notes: Distinct from subcontractor-insurance-expiry-check in jobs/construction (which tracks contractor COIs on a job site) — this tracks tenant renters-insurance compliance required by the lease, only useful where the lease actually mandates coverage.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
id: utility-billback-reconciliation-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: Utility Bill-Back Reconciliation Check
|
|
4
|
+
description: >
|
|
5
|
+
Compares submetered tenant utility charges against the property's
|
|
6
|
+
master utility bill and flags a mismatch beyond a set tolerance. Use
|
|
7
|
+
this if tenant bill-backs have ever quietly drifted from the actual
|
|
8
|
+
master bill, either undercharging the owner or overcharging tenants.
|
|
9
|
+
category: realestate
|
|
10
|
+
tags: [realestate, utilities, billing, reconciliation]
|
|
11
|
+
schedule: "0 8 3 * *"
|
|
12
|
+
timezone: "UTC"
|
|
13
|
+
runner: shell
|
|
14
|
+
command: >
|
|
15
|
+
awk -F',' -v tol="{{tolerance_pct}}" '
|
|
16
|
+
NR==1 {next}
|
|
17
|
+
{
|
|
18
|
+
billed_total += $3;
|
|
19
|
+
master = $2;
|
|
20
|
+
property = $1;
|
|
21
|
+
}
|
|
22
|
+
END {
|
|
23
|
+
diff = billed_total - master;
|
|
24
|
+
pct = (master > 0) ? (diff / master * 100) : 0;
|
|
25
|
+
if (pct < 0) pct = -pct;
|
|
26
|
+
if (pct >= tol) {
|
|
27
|
+
printf "RECONCILIATION MISMATCH: %s — tenant bill-backs total $%.2f vs master bill $%.2f (%.1f%% variance)\n", property, billed_total, master, pct;
|
|
28
|
+
} else {
|
|
29
|
+
printf "OK: %s bill-backs reconcile within tolerance ($%.2f vs $%.2f)\n", property, billed_total, master;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
' "{{billback_csv}}"
|
|
33
|
+
variables:
|
|
34
|
+
billback_csv:
|
|
35
|
+
default: "./utility-billback-ledger.csv"
|
|
36
|
+
description: "CSV with header row, columns: property_name,master_bill_amount,tenant_billed_amount — one row per submetered unit for the current billing period, master_bill_amount repeated per row for the property."
|
|
37
|
+
tolerance_pct:
|
|
38
|
+
default: 5
|
|
39
|
+
description: Allowed percentage variance between total tenant bill-backs and the master bill before it's flagged.
|
|
40
|
+
compatible_agents: [generic, claude, codex]
|
|
41
|
+
notes: Assumes a per-period export of submeter charges alongside the master bill amount — adjust the CSV shape to match your submetering vendor or utility management software's export.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
id: champion-departure-watch
|
|
2
|
+
version: 1
|
|
3
|
+
name: Champion Departure Watch
|
|
4
|
+
description: >
|
|
5
|
+
Checks whether your champion or economic-buyer contact at open or
|
|
6
|
+
recently-closed accounts has left the company, using bounce signals or
|
|
7
|
+
a job-change lookup, and drafts a plan to find the new point of contact.
|
|
8
|
+
Use this if a deal has ever gone quiet for weeks before you found out
|
|
9
|
+
your one internal advocate had already left the company.
|
|
10
|
+
category: sales
|
|
11
|
+
tags: [sales, champion, contact-departure, account-risk]
|
|
12
|
+
schedule: "0 8 * * 1"
|
|
13
|
+
timezone: "UTC"
|
|
14
|
+
runner: agent-prompt
|
|
15
|
+
prompt: |
|
|
16
|
+
Review the champion/decision-maker contacts listed in {{contacts_source}}
|
|
17
|
+
for accounts with an open deal or a contract within
|
|
18
|
+
{{renewal_lookback_days}} days of renewal.
|
|
19
|
+
1. For each contact, check for signs they've left the company: a bounced
|
|
20
|
+
email address, an outdated title, or a job-change signal on
|
|
21
|
+
{{signal_source}} (e.g. LinkedIn).
|
|
22
|
+
2. List any contact flagged as likely departed, with the account name,
|
|
23
|
+
deal/contract at risk, and what signal triggered the flag.
|
|
24
|
+
3. For each flagged account, suggest the most likely replacement contact
|
|
25
|
+
if one is visible in the account (another named stakeholder, or a
|
|
26
|
+
generic role like "VP of [department]"), and draft a short
|
|
27
|
+
re-introduction email to that person or a warm-intro request to
|
|
28
|
+
another contact at the account.
|
|
29
|
+
4. If no departures are found, say so in one line.
|
|
30
|
+
variables:
|
|
31
|
+
contacts_source:
|
|
32
|
+
default: "your CRM's contact list, or a champions.csv with columns: account,contact_name,contact_email,title,deal_or_contract"
|
|
33
|
+
description: Where champion/decision-maker contacts and the account/deal they're tied to are recorded.
|
|
34
|
+
signal_source:
|
|
35
|
+
default: "LinkedIn, or email bounce logs from your email platform"
|
|
36
|
+
description: Where to check for a job-change or departure signal.
|
|
37
|
+
renewal_lookback_days:
|
|
38
|
+
default: 90
|
|
39
|
+
description: How far ahead to include upcoming renewals when scoping which accounts' champions to check.
|
|
40
|
+
compatible_agents: [claude, codex, hermes, openclaw, generic]
|
|
41
|
+
notes: >
|
|
42
|
+
Draft-only — review the suggested replacement contact and re-intro email
|
|
43
|
+
before sending. Respect LinkedIn's terms of use; a manual check or a
|
|
44
|
+
licensed data provider is safer than scraping.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
id: closed-lost-reason-audit
|
|
2
|
+
version: 1
|
|
3
|
+
name: Closed-Lost Reason Audit
|
|
4
|
+
description: >
|
|
5
|
+
Finds recently closed-lost deals with no loss reason recorded, and
|
|
6
|
+
summarizes the reasons that were captured into a short pattern report.
|
|
7
|
+
Use this if closed-lost deals have ever piled up with a blank reason
|
|
8
|
+
field, making it impossible to tell whether you're losing to a
|
|
9
|
+
competitor, on price, or on missing features.
|
|
10
|
+
category: sales
|
|
11
|
+
tags: [sales, closed-lost, win-loss, reporting]
|
|
12
|
+
schedule: "0 8 * * 1"
|
|
13
|
+
timezone: "UTC"
|
|
14
|
+
runner: hybrid
|
|
15
|
+
command: >
|
|
16
|
+
psql "{{database_url}}" -t -c "select name, owner, amount, loss_reason from deals where stage = 'closed_lost' and closed_at > now() - interval '{{lookback_days}} days' order by closed_at desc;"
|
|
17
|
+
prompt: |
|
|
18
|
+
Review closed-lost deals from the last {{lookback_days}} days (from the
|
|
19
|
+
script output above, or by querying {{database_url}} directly).
|
|
20
|
+
1. List every deal with a blank/missing loss_reason — these need a rep
|
|
21
|
+
follow-up to fill in before the data is usable.
|
|
22
|
+
2. For deals that do have a loss_reason, group them into a short summary
|
|
23
|
+
of the top 3-5 recurring themes (e.g. "price", "lost to [competitor]",
|
|
24
|
+
"missing feature X", "no budget/timing").
|
|
25
|
+
3. Note if one theme is trending upward compared to what you'd normally
|
|
26
|
+
expect, so it can be raised with product/pricing.
|
|
27
|
+
script_note: >
|
|
28
|
+
`command` lists closed-lost deals and their recorded (or missing) loss
|
|
29
|
+
reason with zero tokens. `prompt` adds the missing-reason follow-up list
|
|
30
|
+
and the qualitative theme summary across free-text reasons.
|
|
31
|
+
variables:
|
|
32
|
+
database_url:
|
|
33
|
+
default: "postgres://user:pass@host:5432/db"
|
|
34
|
+
description: Connection string for the CRM/deals database.
|
|
35
|
+
lookback_days:
|
|
36
|
+
default: 30
|
|
37
|
+
description: How many days of closed-lost deals to review.
|
|
38
|
+
compatible_agents: [claude, codex, hermes, openclaw, generic]
|
|
39
|
+
notes: >
|
|
40
|
+
Assumes a `deals` table with `stage`, `closed_at`, and a free-text
|
|
41
|
+
`loss_reason` column — adjust to your CRM's schema and loss-reason
|
|
42
|
+
taxonomy if it uses a fixed picklist instead of free text.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
id: commission-payout-tracker
|
|
2
|
+
version: 1
|
|
3
|
+
name: Commission Payout Tracker
|
|
4
|
+
description: >
|
|
5
|
+
Finds closed-won deals whose sales commission hasn't been marked as paid
|
|
6
|
+
even though the payout grace period has passed, and totals what's owed
|
|
7
|
+
per rep. Use this if a rep has ever had to chase finance to find out why
|
|
8
|
+
a commission from weeks ago never showed up in their paycheck.
|
|
9
|
+
category: sales
|
|
10
|
+
tags: [sales, commission, payroll-adjacent, compensation]
|
|
11
|
+
schedule: "0 8 1,15 * *"
|
|
12
|
+
timezone: "UTC"
|
|
13
|
+
runner: shell
|
|
14
|
+
command: >
|
|
15
|
+
psql "{{database_url}}" -t -c "select owner, count(*) as unpaid_deals, sum(amount) as unpaid_revenue, round(sum(amount) * {{commission_rate_pct}} / 100.0, 2) as commission_owed from deals where stage = 'closed_won' and commission_paid = false and closed_at < now() - interval '{{grace_days}} days' group by owner order by commission_owed desc;"
|
|
16
|
+
variables:
|
|
17
|
+
database_url:
|
|
18
|
+
default: "postgres://user:pass@host:5432/db"
|
|
19
|
+
description: Connection string for the CRM/deals database.
|
|
20
|
+
commission_rate_pct:
|
|
21
|
+
default: 10
|
|
22
|
+
description: Flat commission rate percent applied to closed-won revenue, for the estimate.
|
|
23
|
+
grace_days:
|
|
24
|
+
default: 15
|
|
25
|
+
description: Days after close before an unpaid commission counts as overdue for payout.
|
|
26
|
+
compatible_agents: [generic, claude, codex]
|
|
27
|
+
notes: >
|
|
28
|
+
Assumes a `deals` table with a `commission_paid` boolean column and a
|
|
29
|
+
flat commission rate — replace the flat-rate math with your real
|
|
30
|
+
commission plan (tiers, accelerators, clawbacks) if it's more complex.
|
|
31
|
+
This is separate from any HR payroll job — it only flags CRM-side deal
|
|
32
|
+
data, it does not run payroll.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
id: contract-renewal-opportunity-tracker
|
|
2
|
+
version: 1
|
|
3
|
+
name: Contract Renewal Opportunity Tracker
|
|
4
|
+
description: >
|
|
5
|
+
Flags existing customer contracts approaching their renewal date so
|
|
6
|
+
account management can start the renewal conversation early. Use this
|
|
7
|
+
if a contract has ever auto-lapsed or renewed on unfavorable terms
|
|
8
|
+
because nobody flagged it until it was almost too late.
|
|
9
|
+
category: sales
|
|
10
|
+
tags: [sales, renewals, contracts, account-management]
|
|
11
|
+
schedule: "0 8 * * 1-5"
|
|
12
|
+
timezone: "UTC"
|
|
13
|
+
runner: shell
|
|
14
|
+
command: >
|
|
15
|
+
psql "{{database_url}}" -t -c "select customer_name, owner, contract_value, renewal_date from contracts where status = 'active' and renewal_date < now() + interval '{{warn_days}} days' order by renewal_date;"
|
|
16
|
+
variables:
|
|
17
|
+
database_url:
|
|
18
|
+
default: "postgres://user:pass@host:5432/db"
|
|
19
|
+
description: Connection string for the contracts/CRM database.
|
|
20
|
+
warn_days:
|
|
21
|
+
default: 60
|
|
22
|
+
description: Days before renewal_date to start flagging a contract for renewal outreach.
|
|
23
|
+
compatible_agents: [generic, claude, codex]
|
|
24
|
+
notes: >
|
|
25
|
+
Assumes a `contracts` table with `status`, `renewal_date`, `owner`, and
|
|
26
|
+
`contract_value` columns — adjust to your schema. Distinct from
|
|
27
|
+
`quote-expiry-reminder` (pre-sale quotes that haven't been signed yet);
|
|
28
|
+
this tracks signed, active customer contracts nearing their renewal date.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
id: discount-approval-pending-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: Discount Approval Pending Check
|
|
4
|
+
description: >
|
|
5
|
+
Flags deals with a discount above your standard threshold that are
|
|
6
|
+
still waiting on manager approval, especially ones that have been
|
|
7
|
+
sitting for a while. Use this if a rep has ever quoted a customer a
|
|
8
|
+
deep discount and the deal stalled for days waiting on an approval
|
|
9
|
+
nobody knew was pending.
|
|
10
|
+
category: sales
|
|
11
|
+
tags: [sales, discounts, approvals, deal-desk]
|
|
12
|
+
schedule: "0 */4 * * 1-5"
|
|
13
|
+
timezone: "UTC"
|
|
14
|
+
runner: shell
|
|
15
|
+
command: >
|
|
16
|
+
psql "{{database_url}}" -t -c "select name, owner, discount_pct, approval_requested_at from deals where discount_pct >= {{discount_threshold_pct}} and approval_status = 'pending' and approval_requested_at < now() - interval '{{stale_hours}} hours' order by approval_requested_at;"
|
|
17
|
+
variables:
|
|
18
|
+
database_url:
|
|
19
|
+
default: "postgres://user:pass@host:5432/db"
|
|
20
|
+
description: Connection string for the CRM/deals database.
|
|
21
|
+
discount_threshold_pct:
|
|
22
|
+
default: 15
|
|
23
|
+
description: Discount percent that requires manager approval in your process.
|
|
24
|
+
stale_hours:
|
|
25
|
+
default: 24
|
|
26
|
+
description: Hours an approval request can sit pending before it's flagged.
|
|
27
|
+
compatible_agents: [generic, claude, codex]
|
|
28
|
+
notes: >
|
|
29
|
+
Assumes a `deals` table with `discount_pct`, `approval_status`, and
|
|
30
|
+
`approval_requested_at` columns from a deal-desk/CPQ approval workflow
|
|
31
|
+
— adjust field names to match your process.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
id: forecast-submission-compliance-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: Forecast Submission Compliance Check
|
|
4
|
+
description: >
|
|
5
|
+
Compares your active rep roster against submitted forecast records for
|
|
6
|
+
the current period and flags anyone who hasn't submitted yet. Use this
|
|
7
|
+
if sales leadership has ever walked into a forecast review meeting only
|
|
8
|
+
to find out half the team never actually submitted numbers.
|
|
9
|
+
category: sales
|
|
10
|
+
tags: [sales, forecasting, compliance, sales-ops]
|
|
11
|
+
schedule: "0 9 * * 5"
|
|
12
|
+
timezone: "UTC"
|
|
13
|
+
runner: shell
|
|
14
|
+
command: >
|
|
15
|
+
period="{{current_period}}";
|
|
16
|
+
if [ -z "$period" ]; then period=$(date +%G-W%V); fi;
|
|
17
|
+
awk -F',' -v period="$period" '
|
|
18
|
+
NR==FNR { if (FNR>1) reps[$1]=1; next }
|
|
19
|
+
FNR==1 { next }
|
|
20
|
+
$2 == period { submitted[$1]=1 }
|
|
21
|
+
END {
|
|
22
|
+
for (r in reps) {
|
|
23
|
+
if (!(r in submitted)) print "MISSING FORECAST: " r " has not submitted for " period;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
' "{{reps_csv_path}}" "{{forecasts_csv_path}}"
|
|
27
|
+
variables:
|
|
28
|
+
reps_csv_path:
|
|
29
|
+
default: "./active-reps.csv"
|
|
30
|
+
description: "Path to a CSV with header row and column: rep_name — one row per active rep expected to submit a forecast."
|
|
31
|
+
forecasts_csv_path:
|
|
32
|
+
default: "./forecast-submissions.csv"
|
|
33
|
+
description: "Path to a CSV with header row and columns: rep_name,period,submitted_at — one row per submitted forecast."
|
|
34
|
+
current_period:
|
|
35
|
+
default: ""
|
|
36
|
+
description: 'The period identifier to check submissions against (e.g. ISO week or "2026-Q3"). Leave blank to default to the current ISO week (YYYY-Www) — override if your forecasts CSV uses a different period format.'
|
|
37
|
+
compatible_agents: [generic, claude, codex]
|
|
38
|
+
notes: >
|
|
39
|
+
You maintain both CSVs yourself (export active-reps.csv from your HRIS
|
|
40
|
+
or CRM user list, and forecast-submissions.csv from wherever forecasts
|
|
41
|
+
are logged) — the `current_period` value must match how periods are
|
|
42
|
+
written in forecast-submissions.csv exactly.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
id: multi-year-renewal-escalation-tracker
|
|
2
|
+
version: 1
|
|
3
|
+
name: Multi-Year Renewal Escalation Tracker
|
|
4
|
+
description: >
|
|
5
|
+
Flags multi-year contracts approaching their next contract-year
|
|
6
|
+
anniversary, where a pre-agreed price escalation kicks in, so the
|
|
7
|
+
customer gets notice before the higher invoice arrives. Use this if a
|
|
8
|
+
customer has ever been surprised by a built-in price increase on a
|
|
9
|
+
multi-year deal because nobody sent the required notice ahead of the
|
|
10
|
+
anniversary date.
|
|
11
|
+
category: sales
|
|
12
|
+
tags: [sales, renewals, multi-year, pricing, account-management]
|
|
13
|
+
schedule: "0 8 * * 1"
|
|
14
|
+
timezone: "UTC"
|
|
15
|
+
runner: shell
|
|
16
|
+
command: >
|
|
17
|
+
psql "{{database_url}}" -t -c "select customer_name, owner, escalation_pct, next_anniversary_date from multi_year_contracts where next_anniversary_date < now() + interval '{{notice_days}} days' order by next_anniversary_date;"
|
|
18
|
+
variables:
|
|
19
|
+
database_url:
|
|
20
|
+
default: "postgres://user:pass@host:5432/db"
|
|
21
|
+
description: Connection string for the contracts/CRM database.
|
|
22
|
+
notice_days:
|
|
23
|
+
default: 45
|
|
24
|
+
description: Days of advance notice required before a contract's next anniversary/escalation date.
|
|
25
|
+
compatible_agents: [generic, claude, codex]
|
|
26
|
+
notes: >
|
|
27
|
+
Assumes a `multi_year_contracts` table with `next_anniversary_date` and
|
|
28
|
+
`escalation_pct` columns tracking the pre-agreed annual price increase
|
|
29
|
+
— adjust to your schema. Distinct from `contract-renewal-opportunity-tracker`,
|
|
30
|
+
which covers the end-of-term renewal decision rather than an in-term
|
|
31
|
+
contractual price step-up.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
id: pipeline-hygiene-audit
|
|
2
|
+
version: 1
|
|
3
|
+
name: Pipeline Hygiene Audit
|
|
4
|
+
description: >
|
|
5
|
+
Finds open deals missing basic required fields, like an amount, a close
|
|
6
|
+
date, or a next step, so forecasts and reports aren't quietly built on
|
|
7
|
+
bad data. Use this if a forecast has ever been wrong because half the
|
|
8
|
+
pipeline had blank fields nobody was checking for.
|
|
9
|
+
category: sales
|
|
10
|
+
tags: [sales, pipeline, data-quality, crm-hygiene]
|
|
11
|
+
schedule: "0 8 * * 1"
|
|
12
|
+
timezone: "UTC"
|
|
13
|
+
runner: shell
|
|
14
|
+
command: >
|
|
15
|
+
psql "{{database_url}}" -t -c "select name, owner, stage, (case when amount is null then 'missing amount' end) || (case when close_date is null then ' missing close_date' end) || (case when next_step is null or next_step = '' then ' missing next_step' end) as issues from deals where stage not in ('closed_won','closed_lost') and (amount is null or close_date is null or next_step is null or next_step = '');"
|
|
16
|
+
variables:
|
|
17
|
+
database_url:
|
|
18
|
+
default: "postgres://user:pass@host:5432/db"
|
|
19
|
+
description: Connection string for the CRM/deals database.
|
|
20
|
+
compatible_agents: [generic, claude, codex]
|
|
21
|
+
notes: >
|
|
22
|
+
Assumes a `deals` table with `amount`, `close_date`, and `next_step`
|
|
23
|
+
columns — adjust the query and the required-field list to what your
|
|
24
|
+
team actually treats as mandatory. Distinct from `stale-deal-nudge`
|
|
25
|
+
(which flags deals with no recent activity) — this flags deals with
|
|
26
|
+
incomplete data regardless of how recently they were touched.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
id: poc-trial-conversion-tracker
|
|
2
|
+
version: 1
|
|
3
|
+
name: Sales-Led POC Conversion Tracker
|
|
4
|
+
description: >
|
|
5
|
+
Flags sales-assisted proof-of-concept (POC) engagements approaching or
|
|
6
|
+
past their end date with no closed-won or closed-lost outcome recorded.
|
|
7
|
+
Use this if an enterprise POC has ever quietly run past its agreed end
|
|
8
|
+
date with no clear owner pushing toward a decision.
|
|
9
|
+
category: sales
|
|
10
|
+
tags: [sales, poc, enterprise, conversion]
|
|
11
|
+
schedule: "0 8 * * 1-5"
|
|
12
|
+
timezone: "UTC"
|
|
13
|
+
runner: shell
|
|
14
|
+
command: >
|
|
15
|
+
psql "{{database_url}}" -t -c "select account_name, owner, poc_end_date, stage from pocs where stage = 'in_progress' and poc_end_date < now() + interval '{{lookahead_days}} days' order by poc_end_date;"
|
|
16
|
+
variables:
|
|
17
|
+
database_url:
|
|
18
|
+
default: "postgres://user:pass@host:5432/db"
|
|
19
|
+
description: Connection string for the CRM/deals database (a `pocs` table or equivalent stage on `deals`).
|
|
20
|
+
lookahead_days:
|
|
21
|
+
default: 7
|
|
22
|
+
description: How many days ahead (or past, if negative logic is added) to flag a POC nearing its end date.
|
|
23
|
+
compatible_agents: [generic, claude, codex]
|
|
24
|
+
notes: >
|
|
25
|
+
Assumes a `pocs` table (or a `deals` table filtered to a POC stage) with
|
|
26
|
+
`poc_end_date` and `stage` columns — adjust to your CRM's schema. This
|
|
27
|
+
is a sales-assisted enterprise POC tracked in the CRM by a rep, distinct
|
|
28
|
+
from growth's `trial-expiring-nudge`, which tracks self-serve product
|
|
29
|
+
trials nearing expiration.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
id: referral-followup-tracker
|
|
2
|
+
version: 1
|
|
3
|
+
name: Referral Follow-Up Tracker
|
|
4
|
+
description: >
|
|
5
|
+
Flags customer referrals that were asked for or given, and haven't had a
|
|
6
|
+
logged follow-up after a set number of days. Use this if a happy
|
|
7
|
+
customer has ever offered a referral introduction and it fell through
|
|
8
|
+
the cracks because nobody owned the follow-up.
|
|
9
|
+
category: sales
|
|
10
|
+
tags: [sales, referrals, advocacy, follow-up]
|
|
11
|
+
schedule: "0 9 * * 1-5"
|
|
12
|
+
timezone: "UTC"
|
|
13
|
+
runner: shell
|
|
14
|
+
command: >
|
|
15
|
+
awk -F',' -v wait_days="{{wait_days}}" '
|
|
16
|
+
NR==1 {next}
|
|
17
|
+
$5 == "yes" {next}
|
|
18
|
+
{
|
|
19
|
+
customer=$1; referred_contact=$2; requested_date=$3; owner=$4;
|
|
20
|
+
cmd = "date -d \"" requested_date "\" +%s 2>/dev/null || date -j -f %Y-%m-%d \"" requested_date "\" +%s 2>/dev/null";
|
|
21
|
+
cmd | getline req_epoch; close(cmd);
|
|
22
|
+
"date +%s" | getline now_epoch; close("date +%s");
|
|
23
|
+
days = (now_epoch - req_epoch) / 86400;
|
|
24
|
+
if (days >= wait_days) {
|
|
25
|
+
printf "NEEDS FOLLOW-UP: %s referred %s (owner: %s) — %d day(s) since requested\n", customer, referred_contact, owner, days;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
' "{{referrals_csv_path}}"
|
|
29
|
+
variables:
|
|
30
|
+
referrals_csv_path:
|
|
31
|
+
default: "./referrals.csv"
|
|
32
|
+
description: "Path to a CSV with columns: customer_name,referred_contact,requested_date,owner,followed_up (yes/no; requested_date is YYYY-MM-DD)."
|
|
33
|
+
wait_days:
|
|
34
|
+
default: 5
|
|
35
|
+
description: Days after a referral is logged before it's flagged as overdue for a follow-up.
|
|
36
|
+
compatible_agents: [generic, claude, codex]
|
|
37
|
+
notes: >
|
|
38
|
+
You maintain referrals.csv yourself (log it when a customer offers or
|
|
39
|
+
makes an introduction, mark followed_up=yes once the owner reaches out)
|
|
40
|
+
— doesn't integrate with any CRM directly.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
id: territory-coverage-gap-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: Territory Coverage Gap Check
|
|
4
|
+
description: >
|
|
5
|
+
Flags target accounts that have no assigned rep, or have an assigned
|
|
6
|
+
rep but no logged activity in a long time. Use this if an account has
|
|
7
|
+
ever gone completely unworked for months simply because it fell between
|
|
8
|
+
territory reassignments and nobody noticed the gap.
|
|
9
|
+
category: sales
|
|
10
|
+
tags: [sales, territory, account-coverage, ops]
|
|
11
|
+
schedule: "0 8 * * 1"
|
|
12
|
+
timezone: "UTC"
|
|
13
|
+
runner: shell
|
|
14
|
+
command: >
|
|
15
|
+
awk -F',' -v stale_days="{{stale_days}}" '
|
|
16
|
+
NR==1 {next}
|
|
17
|
+
{
|
|
18
|
+
account=$1; rep=$2; last_activity=$3;
|
|
19
|
+
if (rep == "" ) {
|
|
20
|
+
printf "UNASSIGNED: %s has no assigned rep\n", account;
|
|
21
|
+
next;
|
|
22
|
+
}
|
|
23
|
+
cmd = "date -d \"" last_activity "\" +%s 2>/dev/null || date -j -f %Y-%m-%d \"" last_activity "\" +%s 2>/dev/null";
|
|
24
|
+
cmd | getline last_epoch; close(cmd);
|
|
25
|
+
"date +%s" | getline now_epoch; close("date +%s");
|
|
26
|
+
days = (now_epoch - last_epoch) / 86400;
|
|
27
|
+
if (days >= stale_days) {
|
|
28
|
+
printf "NO ACTIVITY: %s (rep: %s) — %d day(s) since last activity\n", account, rep, days;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
' "{{accounts_csv_path}}"
|
|
32
|
+
variables:
|
|
33
|
+
accounts_csv_path:
|
|
34
|
+
default: "./target-accounts.csv"
|
|
35
|
+
description: "Path to a CSV with columns: account_name,assigned_rep,last_activity_date (YYYY-MM-DD; assigned_rep blank if unowned)."
|
|
36
|
+
stale_days:
|
|
37
|
+
default: 45
|
|
38
|
+
description: Days without logged activity on an assigned account before it's flagged as a coverage gap.
|
|
39
|
+
compatible_agents: [generic, claude, codex]
|
|
40
|
+
notes: >
|
|
41
|
+
You maintain target-accounts.csv yourself (or export it from your CRM's
|
|
42
|
+
account list) — this is a coverage/ownership check, not a deal-level
|
|
43
|
+
staleness check (see `stale-deal-nudge` for that).
|
|
@@ -16,6 +16,11 @@ export const ALLOWED_DUPLICATE_PAIRS = [
|
|
|
16
16
|
"warranty-claim-expiry-check",
|
|
17
17
|
"Same deadline-check pattern, different domains — automotive repair-order warranty claims vs. HVAC/appliance manufacturer warranty claims.",
|
|
18
18
|
],
|
|
19
|
+
[
|
|
20
|
+
"claim-status-check",
|
|
21
|
+
"landlord-insurance-claim-status-check",
|
|
22
|
+
"Same stale-claim-followup goal, different mechanism and scale — generic insurance job is agent-prompt for a single policyholder's claims; realestate job is a zero-token shell scan over a property portfolio's claims CSV.",
|
|
23
|
+
],
|
|
19
24
|
];
|
|
20
25
|
|
|
21
26
|
export function isAllowedPair(idA, idB) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wonsukchoi/crondex",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "A public directory of pre-made, agent-editable cron jobs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"lint-shell": "node scripts/lint-shell.js",
|
|
39
39
|
"check-duplicates": "node scripts/check-duplicates.js",
|
|
40
40
|
"smoke-test": "node scripts/smoke-test.js",
|
|
41
|
-
"test": "node --test"
|
|
41
|
+
"test": "node --test \"test/*.test.js\""
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"js-yaml": "^4.1.0"
|