@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.
Files changed (75) hide show
  1. package/README.md +39 -27
  2. package/bin/crondex.js +41 -6
  3. package/catalog.json +1865 -65
  4. package/jobs/agriculture/crop-price-market-watch.yaml +32 -0
  5. package/jobs/agriculture/livestock-feed-stock-check.yaml +35 -0
  6. package/jobs/automotive/loaner-vehicle-return-reminder.yaml +35 -0
  7. package/jobs/automotive/parts-backorder-check.yaml +33 -0
  8. package/jobs/automotive/repair-order-aging-check.yaml +35 -0
  9. package/jobs/childcare/immunization-record-compliance-check.yaml +33 -0
  10. package/jobs/childcare/staff-child-ratio-compliance-check.yaml +30 -0
  11. package/jobs/childcare/tuition-payment-late-check.yaml +35 -0
  12. package/jobs/construction/equipment-rental-return-reminder.yaml +35 -0
  13. package/jobs/construction/subcontractor-insurance-expiry-check.yaml +35 -0
  14. package/jobs/creator/sponsorship-deliverable-tracker.yaml +38 -0
  15. package/jobs/crypto/defi-liquidation-risk-watch.yaml +36 -0
  16. package/jobs/crypto/token-unlock-vesting-watch.yaml +34 -0
  17. package/jobs/ecommerce/checkout-conversion-drop-watch.yaml +39 -0
  18. package/jobs/ecommerce/negative-review-alert.yaml +35 -0
  19. package/jobs/education/at-risk-student-grade-watch.yaml +35 -0
  20. package/jobs/education/field-trip-permission-slip-check.yaml +36 -0
  21. package/jobs/events/attendee-checkin-rate-watch.yaml +37 -0
  22. package/jobs/events/event-staffing-shortfall-check.yaml +34 -0
  23. package/jobs/fitness/class-utilization-check.yaml +32 -0
  24. package/jobs/fitness/gym-equipment-maintenance-check.yaml +35 -0
  25. package/jobs/fitness/gym-membership-renewal-reminder.yaml +35 -0
  26. package/jobs/fleet/driver-license-cdl-expiry-check.yaml +35 -0
  27. package/jobs/fleet/vehicle-inspection-due-check.yaml +35 -0
  28. package/jobs/gaming/game-server-uptime-check.yaml +34 -0
  29. package/jobs/gaming/tournament-registration-deadline-check.yaml +34 -0
  30. package/jobs/government/constituent-casework-followup-check.yaml +33 -0
  31. package/jobs/government/foia-request-deadline-check.yaml +36 -0
  32. package/jobs/government/permit-application-backlog-check.yaml +37 -0
  33. package/jobs/healthcare/insurance-eligibility-verification-check.yaml +32 -0
  34. package/jobs/healthcare/lab-result-followup-check.yaml +34 -0
  35. package/jobs/hiring/background-check-status-check.yaml +35 -0
  36. package/jobs/hiring/interview-feedback-overdue-check.yaml +33 -0
  37. package/jobs/hospitality/guest-maintenance-request-backlog-check.yaml +35 -0
  38. package/jobs/hospitality/guest-review-response-check.yaml +35 -0
  39. package/jobs/hr/exit-interview-completion-check.yaml +33 -0
  40. package/jobs/hr/performance-review-cycle-reminder.yaml +34 -0
  41. package/jobs/insurance/certificate-of-insurance-request-check.yaml +38 -0
  42. package/jobs/insurance/premium-payment-due-reminder.yaml +35 -0
  43. package/jobs/inventory/inventory-shrinkage-watch.yaml +36 -0
  44. package/jobs/inventory/low-stock-alert.yaml +7 -4
  45. package/jobs/inventory/overstock-slow-mover-check.yaml +36 -0
  46. package/jobs/investing/earnings-calendar-watch.yaml +32 -0
  47. package/jobs/investing/tax-loss-harvesting-review.yaml +33 -0
  48. package/jobs/legal/compliance-filing-deadline-reminder.yaml +38 -0
  49. package/jobs/legal/court-deadline-reminder.yaml +40 -0
  50. package/jobs/logistics/container-demurrage-fee-watch.yaml +35 -0
  51. package/jobs/logistics/last-mile-delivery-exception-check.yaml +36 -0
  52. package/jobs/manufacturing/raw-material-shortage-risk-check.yaml +31 -0
  53. package/jobs/manufacturing/supplier-otd-performance-watch.yaml +38 -0
  54. package/jobs/marketing/campaign-utm-tracking-check.yaml +41 -0
  55. package/jobs/nonprofit/board-action-item-followup-check.yaml +28 -0
  56. package/jobs/nonprofit/grant-reporting-deadline-check.yaml +38 -0
  57. package/jobs/podcast/podcast-download-drop-watch.yaml +42 -0
  58. package/jobs/podcast/podcast-rating-review-watch.yaml +37 -0
  59. package/jobs/realestate/property-maintenance-inspection-reminder.yaml +35 -0
  60. package/jobs/realestate/property-tax-deadline-reminder.yaml +35 -0
  61. package/jobs/restaurant/food-cost-percentage-watch.yaml +35 -0
  62. package/jobs/restaurant/labor-cost-percentage-watch.yaml +36 -0
  63. package/jobs/retail/employee-shift-gap-check.yaml +35 -0
  64. package/jobs/retail/pos-till-reconciliation-check.yaml +33 -0
  65. package/jobs/retail/store-opening-checklist-reminder.yaml +30 -0
  66. package/jobs/support/agent-workload-balance-check.yaml +30 -0
  67. package/jobs/support/ticket-reopened-rate-watch.yaml +35 -0
  68. package/jobs/team/on-call-fatigue-check.yaml +39 -0
  69. package/jobs/veterinary/boarding-checkout-reminder.yaml +29 -0
  70. package/jobs/veterinary/controlled-substance-log-audit.yaml +33 -0
  71. package/jobs/veterinary/pet-vaccine-due-reminder.yaml +34 -0
  72. package/jobs/warehousing/climate-control-compliance-check.yaml +40 -0
  73. package/jobs/warehousing/dock-schedule-conflict-check.yaml +30 -0
  74. package/jobs/warehousing/pick-pack-error-rate-watch.yaml +35 -0
  75. 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
- 187 jobs across 37 categories:
94
+ 257 jobs across 44 categories:
91
95
 
92
96
  | category | jobs |
93
97
  |---|---|
94
- | `agriculture` | 3 |
95
- | `construction` | 3 |
98
+ | `agriculture` | 5 |
99
+ | `automotive` | 3 |
100
+ | `childcare` | 3 |
101
+ | `construction` | 5 |
96
102
  | `content` | 13 |
97
- | `creator` | 4 |
98
- | `crypto` | 3 |
103
+ | `creator` | 5 |
104
+ | `crypto` | 5 |
99
105
  | `devops` | 26 |
100
- | `ecommerce` | 3 |
101
- | `education` | 3 |
102
- | `events` | 3 |
106
+ | `ecommerce` | 5 |
107
+ | `education` | 5 |
108
+ | `events` | 5 |
103
109
  | `finance` | 10 |
104
- | `fleet` | 3 |
105
- | `gaming` | 3 |
110
+ | `fitness` | 3 |
111
+ | `fleet` | 5 |
112
+ | `gaming` | 5 |
113
+ | `government` | 3 |
106
114
  | `growth` | 5 |
107
- | `healthcare` | 3 |
108
- | `hiring` | 3 |
115
+ | `healthcare` | 5 |
116
+ | `hiring` | 5 |
109
117
  | `home` | 5 |
110
- | `hospitality` | 3 |
111
- | `hr` | 3 |
112
- | `insurance` | 3 |
113
- | `inventory` | 3 |
114
- | `investing` | 3 |
118
+ | `hospitality` | 5 |
119
+ | `hr` | 5 |
120
+ | `insurance` | 5 |
121
+ | `inventory` | 5 |
122
+ | `investing` | 5 |
115
123
  | `learning` | 5 |
116
- | `legal` | 3 |
117
- | `logistics` | 3 |
118
- | `manufacturing` | 3 |
119
- | `marketing` | 4 |
120
- | `nonprofit` | 3 |
124
+ | `legal` | 5 |
125
+ | `logistics` | 5 |
126
+ | `manufacturing` | 5 |
127
+ | `marketing` | 5 |
128
+ | `nonprofit` | 5 |
121
129
  | `personal` | 9 |
122
- | `podcast` | 3 |
130
+ | `podcast` | 5 |
123
131
  | `productivity` | 9 |
124
- | `realestate` | 3 |
125
- | `restaurant` | 3 |
132
+ | `realestate` | 5 |
133
+ | `restaurant` | 5 |
134
+ | `retail` | 3 |
126
135
  | `sales` | 5 |
127
136
  | `security` | 14 |
128
- | `support` | 3 |
129
- | `team` | 4 |
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
- console.log(readFileSync(join(ROOT, findJob(id).path), "utf8"));
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 Object.entries(counts).sort(([a], [b]) => a.localeCompare(b))) {
140
+ for (const [cat, n] of sorted) {
106
141
  console.log(`${cat} (${n})`);
107
142
  }
108
143
  }