@wonsukchoi/crondex 0.10.0 → 0.12.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 +39 -27
- package/bin/crondex.js +41 -6
- package/catalog.json +1865 -65
- package/jobs/agriculture/crop-price-market-watch.yaml +32 -0
- package/jobs/agriculture/livestock-feed-stock-check.yaml +35 -0
- package/jobs/automotive/loaner-vehicle-return-reminder.yaml +35 -0
- package/jobs/automotive/parts-backorder-check.yaml +33 -0
- package/jobs/automotive/repair-order-aging-check.yaml +35 -0
- package/jobs/childcare/immunization-record-compliance-check.yaml +33 -0
- package/jobs/childcare/staff-child-ratio-compliance-check.yaml +30 -0
- package/jobs/childcare/tuition-payment-late-check.yaml +35 -0
- package/jobs/construction/equipment-rental-return-reminder.yaml +35 -0
- package/jobs/construction/subcontractor-insurance-expiry-check.yaml +35 -0
- package/jobs/creator/sponsorship-deliverable-tracker.yaml +38 -0
- package/jobs/crypto/defi-liquidation-risk-watch.yaml +36 -0
- package/jobs/crypto/token-unlock-vesting-watch.yaml +34 -0
- package/jobs/ecommerce/checkout-conversion-drop-watch.yaml +39 -0
- package/jobs/ecommerce/negative-review-alert.yaml +35 -0
- package/jobs/education/at-risk-student-grade-watch.yaml +35 -0
- package/jobs/education/field-trip-permission-slip-check.yaml +36 -0
- package/jobs/events/attendee-checkin-rate-watch.yaml +37 -0
- package/jobs/events/event-staffing-shortfall-check.yaml +34 -0
- package/jobs/fitness/class-utilization-check.yaml +32 -0
- package/jobs/fitness/gym-equipment-maintenance-check.yaml +35 -0
- package/jobs/fitness/gym-membership-renewal-reminder.yaml +35 -0
- package/jobs/fleet/driver-license-cdl-expiry-check.yaml +35 -0
- package/jobs/fleet/vehicle-inspection-due-check.yaml +35 -0
- package/jobs/gaming/game-server-uptime-check.yaml +34 -0
- package/jobs/gaming/tournament-registration-deadline-check.yaml +34 -0
- package/jobs/government/constituent-casework-followup-check.yaml +33 -0
- package/jobs/government/foia-request-deadline-check.yaml +36 -0
- package/jobs/government/permit-application-backlog-check.yaml +37 -0
- package/jobs/healthcare/insurance-eligibility-verification-check.yaml +32 -0
- package/jobs/healthcare/lab-result-followup-check.yaml +34 -0
- package/jobs/hiring/background-check-status-check.yaml +35 -0
- package/jobs/hiring/interview-feedback-overdue-check.yaml +33 -0
- package/jobs/hospitality/guest-maintenance-request-backlog-check.yaml +35 -0
- package/jobs/hospitality/guest-review-response-check.yaml +35 -0
- package/jobs/hr/exit-interview-completion-check.yaml +33 -0
- package/jobs/hr/performance-review-cycle-reminder.yaml +34 -0
- package/jobs/insurance/certificate-of-insurance-request-check.yaml +38 -0
- package/jobs/insurance/premium-payment-due-reminder.yaml +35 -0
- package/jobs/inventory/inventory-shrinkage-watch.yaml +36 -0
- package/jobs/inventory/low-stock-alert.yaml +7 -4
- package/jobs/inventory/overstock-slow-mover-check.yaml +36 -0
- package/jobs/investing/earnings-calendar-watch.yaml +32 -0
- package/jobs/investing/tax-loss-harvesting-review.yaml +33 -0
- package/jobs/legal/compliance-filing-deadline-reminder.yaml +38 -0
- package/jobs/legal/court-deadline-reminder.yaml +40 -0
- package/jobs/logistics/container-demurrage-fee-watch.yaml +35 -0
- package/jobs/logistics/last-mile-delivery-exception-check.yaml +36 -0
- package/jobs/manufacturing/raw-material-shortage-risk-check.yaml +31 -0
- package/jobs/manufacturing/supplier-otd-performance-watch.yaml +38 -0
- package/jobs/marketing/campaign-utm-tracking-check.yaml +41 -0
- package/jobs/nonprofit/board-action-item-followup-check.yaml +28 -0
- package/jobs/nonprofit/grant-reporting-deadline-check.yaml +38 -0
- package/jobs/podcast/podcast-download-drop-watch.yaml +42 -0
- package/jobs/podcast/podcast-rating-review-watch.yaml +37 -0
- package/jobs/realestate/property-maintenance-inspection-reminder.yaml +35 -0
- package/jobs/realestate/property-tax-deadline-reminder.yaml +35 -0
- package/jobs/restaurant/food-cost-percentage-watch.yaml +35 -0
- package/jobs/restaurant/labor-cost-percentage-watch.yaml +36 -0
- package/jobs/retail/employee-shift-gap-check.yaml +35 -0
- package/jobs/retail/pos-till-reconciliation-check.yaml +33 -0
- package/jobs/retail/store-opening-checklist-reminder.yaml +30 -0
- package/jobs/support/agent-workload-balance-check.yaml +30 -0
- package/jobs/support/ticket-reopened-rate-watch.yaml +35 -0
- package/jobs/team/on-call-fatigue-check.yaml +39 -0
- package/jobs/veterinary/boarding-checkout-reminder.yaml +29 -0
- package/jobs/veterinary/controlled-substance-log-audit.yaml +33 -0
- package/jobs/veterinary/pet-vaccine-due-reminder.yaml +34 -0
- package/jobs/warehousing/climate-control-compliance-check.yaml +40 -0
- package/jobs/warehousing/dock-schedule-conflict-check.yaml +30 -0
- package/jobs/warehousing/pick-pack-error-rate-watch.yaml +35 -0
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -36,6 +36,10 @@ npx @wonsukchoi/crondex add ssl-cert-expiry-check --dest ./cron/ssl-cert-expiry-
|
|
|
36
36
|
- `add <id> [--dest path]` — copy it into your project to edit
|
|
37
37
|
- `init <id> [--category x]` — scaffold a brand-new job from the template
|
|
38
38
|
|
|
39
|
+
Add `--json` to `list`/`categories`/`show`/`recommend` for machine-readable
|
|
40
|
+
output — useful when an agent is parsing the result programmatically
|
|
41
|
+
instead of a human reading it.
|
|
42
|
+
|
|
39
43
|
No install needed — `npx` always runs against the latest catalog. Prefer
|
|
40
44
|
installing once? `npm install -g @wonsukchoi/crondex`, then drop the `npx`
|
|
41
45
|
prefix (run `npm update -g` later to pick up new jobs). Prefer no npm at
|
|
@@ -87,47 +91,54 @@ tags, variables) use `crondex list`, `crondex recommend`, or browse
|
|
|
87
91
|
`jobs/<category>/` directly.
|
|
88
92
|
|
|
89
93
|
<!-- BEGIN JOB SUMMARY -->
|
|
90
|
-
|
|
94
|
+
257 jobs across 44 categories:
|
|
91
95
|
|
|
92
96
|
| category | jobs |
|
|
93
97
|
|---|---|
|
|
94
|
-
| `agriculture` |
|
|
95
|
-
| `
|
|
98
|
+
| `agriculture` | 5 |
|
|
99
|
+
| `automotive` | 3 |
|
|
100
|
+
| `childcare` | 3 |
|
|
101
|
+
| `construction` | 5 |
|
|
96
102
|
| `content` | 13 |
|
|
97
|
-
| `creator` |
|
|
98
|
-
| `crypto` |
|
|
103
|
+
| `creator` | 5 |
|
|
104
|
+
| `crypto` | 5 |
|
|
99
105
|
| `devops` | 26 |
|
|
100
|
-
| `ecommerce` |
|
|
101
|
-
| `education` |
|
|
102
|
-
| `events` |
|
|
106
|
+
| `ecommerce` | 5 |
|
|
107
|
+
| `education` | 5 |
|
|
108
|
+
| `events` | 5 |
|
|
103
109
|
| `finance` | 10 |
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
110
|
+
| `fitness` | 3 |
|
|
111
|
+
| `fleet` | 5 |
|
|
112
|
+
| `gaming` | 5 |
|
|
113
|
+
| `government` | 3 |
|
|
106
114
|
| `growth` | 5 |
|
|
107
|
-
| `healthcare` |
|
|
108
|
-
| `hiring` |
|
|
115
|
+
| `healthcare` | 5 |
|
|
116
|
+
| `hiring` | 5 |
|
|
109
117
|
| `home` | 5 |
|
|
110
|
-
| `hospitality` |
|
|
111
|
-
| `hr` |
|
|
112
|
-
| `insurance` |
|
|
113
|
-
| `inventory` |
|
|
114
|
-
| `investing` |
|
|
118
|
+
| `hospitality` | 5 |
|
|
119
|
+
| `hr` | 5 |
|
|
120
|
+
| `insurance` | 5 |
|
|
121
|
+
| `inventory` | 5 |
|
|
122
|
+
| `investing` | 5 |
|
|
115
123
|
| `learning` | 5 |
|
|
116
|
-
| `legal` |
|
|
117
|
-
| `logistics` |
|
|
118
|
-
| `manufacturing` |
|
|
119
|
-
| `marketing` |
|
|
120
|
-
| `nonprofit` |
|
|
124
|
+
| `legal` | 5 |
|
|
125
|
+
| `logistics` | 5 |
|
|
126
|
+
| `manufacturing` | 5 |
|
|
127
|
+
| `marketing` | 5 |
|
|
128
|
+
| `nonprofit` | 5 |
|
|
121
129
|
| `personal` | 9 |
|
|
122
|
-
| `podcast` |
|
|
130
|
+
| `podcast` | 5 |
|
|
123
131
|
| `productivity` | 9 |
|
|
124
|
-
| `realestate` |
|
|
125
|
-
| `restaurant` |
|
|
132
|
+
| `realestate` | 5 |
|
|
133
|
+
| `restaurant` | 5 |
|
|
134
|
+
| `retail` | 3 |
|
|
126
135
|
| `sales` | 5 |
|
|
127
136
|
| `security` | 14 |
|
|
128
|
-
| `support` |
|
|
129
|
-
| `team` |
|
|
137
|
+
| `support` | 5 |
|
|
138
|
+
| `team` | 5 |
|
|
130
139
|
| `travel` | 5 |
|
|
140
|
+
| `veterinary` | 3 |
|
|
141
|
+
| `warehousing` | 3 |
|
|
131
142
|
<!-- END JOB SUMMARY -->
|
|
132
143
|
|
|
133
144
|
---
|
|
@@ -136,6 +147,7 @@ tags, variables) use `crondex list`, `crondex recommend`, or browse
|
|
|
136
147
|
|
|
137
148
|
```
|
|
138
149
|
crondex/
|
|
150
|
+
├── llms.txt agent-discovery manifest (llms.txt convention)
|
|
139
151
|
├── bin/crondex.js CLI: list / categories / show / add / recommend / init
|
|
140
152
|
├── lib/recommend.js recommend's scoring logic (unit tested in test/)
|
|
141
153
|
├── catalog.json generated index of every job — read this first
|
package/bin/crondex.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// CLI over catalog.json — browse jobs, read one, or pull one into your project.
|
|
3
3
|
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
|
+
import yaml from "js-yaml";
|
|
5
6
|
import { tokenize, rankJobs } from "../lib/recommend.js";
|
|
6
7
|
|
|
7
8
|
const ROOT = new URL("..", import.meta.url).pathname;
|
|
@@ -15,6 +16,14 @@ function flag(name) {
|
|
|
15
16
|
return i === -1 ? undefined : args[i + 1];
|
|
16
17
|
}
|
|
17
18
|
|
|
19
|
+
function hasFlag(name) {
|
|
20
|
+
return args.includes(`--${name}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function printJson(value) {
|
|
24
|
+
console.log(JSON.stringify(value, null, 2));
|
|
25
|
+
}
|
|
26
|
+
|
|
18
27
|
function findJob(id) {
|
|
19
28
|
const meta = CATALOG.jobs.find((j) => j.id === id);
|
|
20
29
|
if (!meta) {
|
|
@@ -28,11 +37,11 @@ function printHelp() {
|
|
|
28
37
|
console.log(`crondex — browse and pull pre-made cron jobs
|
|
29
38
|
|
|
30
39
|
Usage:
|
|
31
|
-
crondex list [--category <name>] [--tag <name>]
|
|
32
|
-
crondex categories
|
|
33
|
-
crondex show <id>
|
|
40
|
+
crondex list [--category <name>] [--tag <name>] [--json]
|
|
41
|
+
crondex categories [--json]
|
|
42
|
+
crondex show <id> [--json]
|
|
34
43
|
crondex add <id> [--dest <path>]
|
|
35
|
-
crondex recommend "<what you want done>" [--limit <n>]
|
|
44
|
+
crondex recommend "<what you want done>" [--limit <n>] [--json]
|
|
36
45
|
crondex init <id> [--category <name>] [--dest <path>]
|
|
37
46
|
|
|
38
47
|
Examples:
|
|
@@ -42,20 +51,39 @@ Examples:
|
|
|
42
51
|
crondex add backup-reminder --dest ./cron/backup-reminder.yaml
|
|
43
52
|
crondex recommend "warn me before my SSL cert expires"
|
|
44
53
|
crondex init ssl-cert-expiry-check --category security
|
|
54
|
+
|
|
55
|
+
Add --json to list/categories/show/recommend for machine-readable output —
|
|
56
|
+
useful when an agent is parsing crondex's output programmatically instead
|
|
57
|
+
of a human reading it.
|
|
45
58
|
`);
|
|
46
59
|
}
|
|
47
60
|
|
|
48
61
|
function recommend(queryText) {
|
|
49
62
|
const limit = Number(flag("limit")) || 5;
|
|
63
|
+
const json = hasFlag("json");
|
|
50
64
|
if (!tokenize(queryText).length) {
|
|
65
|
+
if (json) return printJson([]);
|
|
51
66
|
console.log("query too vague to match on — describe what you want the job to check or remind you about.");
|
|
52
67
|
return;
|
|
53
68
|
}
|
|
54
69
|
const ranked = rankJobs(CATALOG.jobs, queryText, limit);
|
|
55
70
|
if (!ranked.length) {
|
|
71
|
+
if (json) return printJson([]);
|
|
56
72
|
console.log(`no confident match for "${queryText}". Run "crondex list" to browse everything.`);
|
|
57
73
|
return;
|
|
58
74
|
}
|
|
75
|
+
if (json) {
|
|
76
|
+
return printJson(
|
|
77
|
+
ranked.map((r) => ({
|
|
78
|
+
id: r.job.id,
|
|
79
|
+
category: r.job.category,
|
|
80
|
+
score: r.score,
|
|
81
|
+
matched_terms: r.matchedTerms,
|
|
82
|
+
modes: r.job.modes,
|
|
83
|
+
description: r.job.description,
|
|
84
|
+
}))
|
|
85
|
+
);
|
|
86
|
+
}
|
|
59
87
|
console.log(`top match${ranked.length > 1 ? "es" : ""} for "${queryText}":`);
|
|
60
88
|
console.log();
|
|
61
89
|
for (const r of ranked) {
|
|
@@ -77,9 +105,11 @@ function catalogInfoLine() {
|
|
|
77
105
|
function list() {
|
|
78
106
|
const category = flag("category");
|
|
79
107
|
const tag = flag("tag");
|
|
108
|
+
const json = hasFlag("json");
|
|
80
109
|
const jobs = CATALOG.jobs.filter(
|
|
81
110
|
(j) => (!category || j.category === category) && (!tag || j.tags.includes(tag))
|
|
82
111
|
);
|
|
112
|
+
if (json) return printJson(jobs);
|
|
83
113
|
console.log(catalogInfoLine());
|
|
84
114
|
console.log();
|
|
85
115
|
if (!jobs.length) {
|
|
@@ -94,15 +124,20 @@ function list() {
|
|
|
94
124
|
}
|
|
95
125
|
|
|
96
126
|
function show(id) {
|
|
97
|
-
|
|
127
|
+
const meta = findJob(id);
|
|
128
|
+
const raw = readFileSync(join(ROOT, meta.path), "utf8");
|
|
129
|
+
if (hasFlag("json")) return printJson(yaml.load(raw));
|
|
130
|
+
console.log(raw);
|
|
98
131
|
}
|
|
99
132
|
|
|
100
133
|
function categories() {
|
|
101
134
|
const counts = {};
|
|
102
135
|
for (const j of CATALOG.jobs) counts[j.category] = (counts[j.category] ?? 0) + 1;
|
|
136
|
+
const sorted = Object.entries(counts).sort(([a], [b]) => a.localeCompare(b));
|
|
137
|
+
if (hasFlag("json")) return printJson(sorted.map(([category, count]) => ({ category, count })));
|
|
103
138
|
console.log(catalogInfoLine());
|
|
104
139
|
console.log();
|
|
105
|
-
for (const [cat, n] of
|
|
140
|
+
for (const [cat, n] of sorted) {
|
|
106
141
|
console.log(`${cat} (${n})`);
|
|
107
142
|
}
|
|
108
143
|
}
|