jd-intel 0.5.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.
@@ -1,18 +1,33 @@
1
- [
2
- {"slug": "polestar", "name": "Polestar", "sector": "automotive / ev"},
3
- {"slug": "quinyx", "name": "Quinyx", "sector": "workforce management"},
4
- {"slug": "qliro", "name": "Qliro", "sector": "payments"},
5
- {"slug": "tibber", "name": "Tibber", "sector": "energy tech"},
6
- {"slug": "funnel", "name": "Funnel", "sector": "marketing data"},
7
- {"slug": "anyfin", "name": "Anyfin", "sector": "fintech"},
8
- {"slug": "hedvig", "name": "Hedvig", "sector": "insurtech"},
9
- {"slug": "juni", "name": "Juni", "sector": "fintech"},
10
- {"slug": "bambuser", "name": "Bambuser", "sector": "live video commerce"},
11
- {"slug": "karma", "name": "Karma", "sector": "sustainability"},
12
- {"slug": "mate", "name": "Mate", "sector": "e-mobility"},
13
- {"slug": "billogram", "name": "Billogram", "sector": "fintech / billing"},
14
- {"slug": "detectify", "name": "Detectify", "sector": "security"},
15
- {"slug": "storytel", "name": "Storytel", "sector": "audiobooks"},
16
- {"slug": "oneflow", "name": "Oneflow", "sector": "contract management"},
17
- {"slug": "crunchbase", "name": "Crunchbase", "sector": "company data"}
18
- ]
1
+ [
2
+ {"slug": "polestar", "name": "Polestar", "sector": "automotive / ev"},
3
+ {"slug": "quinyx", "name": "Quinyx", "sector": "workforce management"},
4
+ {"slug": "qliro", "name": "Qliro", "sector": "payments"},
5
+ {"slug": "tibber", "name": "Tibber", "sector": "energy tech"},
6
+ {"slug": "funnel", "name": "Funnel", "sector": "marketing data"},
7
+ {"slug": "anyfin", "name": "Anyfin", "sector": "fintech"},
8
+ {"slug": "hedvig", "name": "Hedvig", "sector": "insurtech"},
9
+ {"slug": "juni", "name": "Juni", "sector": "fintech"},
10
+ {"slug": "bambuser", "name": "Bambuser", "sector": "live video commerce"},
11
+ {"slug": "karma", "name": "Karma", "sector": "sustainability"},
12
+ {"slug": "mate", "name": "Mate", "sector": "e-mobility"},
13
+ {"slug": "billogram", "name": "Billogram", "sector": "fintech / billing"},
14
+ {"slug": "detectify", "name": "Detectify", "sector": "security"},
15
+ {"slug": "storytel", "name": "Storytel", "sector": "audiobooks"},
16
+ {"slug": "oneflow", "name": "Oneflow", "sector": "contract management"},
17
+ {"slug": "crunchbase", "name": "Crunchbase", "sector": "company data"},
18
+ {"slug": "teamblue", "name": "team.blue", "sector": "web hosting / infrastructure"},
19
+ {"slug": "recruitgo", "name": "RecruitGo", "sector": "global eor / staffing"},
20
+ {"slug": "merlindigitalpartner-1613753675", "name": "Merlin Digital Partner", "sector": "tech recruitment"},
21
+ {"slug": "techseed", "name": "TechSeed", "sector": "tech staffing"},
22
+ {"slug": "nordicknotsab", "name": "Nordic Knots", "sector": "interior design / d2c"},
23
+ {"slug": "dfdsdenmark", "name": "DFDS Denmark", "sector": "shipping / logistics"},
24
+ {"slug": "career", "name": "Teamtailor", "sector": "hr tech / ats"},
25
+ {"slug": "ecoonline", "name": "EcoOnline", "sector": "ehs software"},
26
+ {"slug": "thestudio", "name": "THE/STUDIO", "sector": "custom manufacturing"},
27
+ {"slug": "tribes", "name": "TRIBES", "sector": "executive search"},
28
+ {"slug": "accrease", "name": "Accrease", "sector": "martech consultancy"},
29
+ {"slug": "finteqhub", "name": "FinteqHub", "sector": "fintech / payments"},
30
+ {"slug": "goodgamestudios", "name": "Goodgame Studios", "sector": "gaming"},
31
+ {"slug": "estonew", "name": "ESTO", "sector": "fintech / consumer credit"},
32
+ {"slug": "cigames", "name": "CI Games", "sector": "gaming"}
33
+ ]
@@ -1,8 +1,29 @@
1
- [
2
- {"slug": "cisco", "name": "Cisco", "sector": "networking", "config": {"tenant": "cisco", "env": "wd5", "site": "Cisco_Careers"}},
3
- {"slug": "salesforce", "name": "Salesforce", "sector": "crm / saas", "config": {"tenant": "salesforce", "env": "wd12", "site": "External_Career_Site"}},
4
- {"slug": "bankofamerica", "name": "Bank of America", "sector": "banking", "config": {"tenant": "ghr", "env": "wd1", "site": "Lateral-US"}},
5
- {"slug": "adobe", "name": "Adobe", "sector": "creative software", "config": {"tenant": "adobe", "env": "wd5", "site": "external_experienced"}},
6
- {"slug": "nvidia", "name": "Nvidia", "sector": "semiconductors", "config": {"tenant": "nvidia", "env": "wd5", "site": "NVIDIAExternalCareerSite"}},
7
- {"slug": "servicetitan", "name": "ServiceTitan", "sector": "vertical saas", "config": {"tenant": "servicetitan", "env": "wd1", "site": "ServiceTitan"}}
8
- ]
1
+ [
2
+ {"slug": "cisco", "name": "Cisco", "sector": "networking", "config": {"tenant": "cisco", "env": "wd5", "site": "Cisco_Careers"}},
3
+ {"slug": "salesforce", "name": "Salesforce", "sector": "crm / saas", "config": {"tenant": "salesforce", "env": "wd12", "site": "External_Career_Site"}},
4
+ {"slug": "bankofamerica", "name": "Bank of America", "sector": "banking", "config": {"tenant": "ghr", "env": "wd1", "site": "Lateral-US"}},
5
+ {"slug": "adobe", "name": "Adobe", "sector": "creative software", "config": {"tenant": "adobe", "env": "wd5", "site": "external_experienced"}},
6
+ {"slug": "nvidia", "name": "Nvidia", "sector": "semiconductors", "config": {"tenant": "nvidia", "env": "wd5", "site": "NVIDIAExternalCareerSite"}},
7
+ {"slug": "servicetitan", "name": "ServiceTitan", "sector": "vertical saas", "config": {"tenant": "servicetitan", "env": "wd1", "site": "ServiceTitan"}},
8
+ {"slug": "cvshealth", "name": "CVS Health", "sector": "healthcare / pharmacy", "config": {"tenant": "cvshealth", "env": "wd1", "site": "CVS_Health_Careers"}},
9
+ {"slug": "target", "name": "Target", "sector": "retail", "config": {"tenant": "target", "env": "wd5", "site": "targetcareers"}},
10
+ {"slug": "rbc", "name": "Royal Bank of Canada", "sector": "banking", "config": {"tenant": "rbc", "env": "wd3", "site": "RBCGLOBAL1"}},
11
+ {"slug": "capitalone", "name": "Capital One", "sector": "banking / fintech", "config": {"tenant": "capitalone", "env": "wd12", "site": "Capital_One"}},
12
+ {"slug": "bmo", "name": "Bank of Montreal", "sector": "banking", "config": {"tenant": "bmo", "env": "wd3", "site": "External"}},
13
+ {"slug": "hpe", "name": "Hewlett Packard Enterprise", "sector": "enterprise tech", "config": {"tenant": "hpe", "env": "wd5", "site": "Jobsathpe"}},
14
+ {"slug": "mastercard", "name": "Mastercard", "sector": "payments", "config": {"tenant": "mastercard", "env": "wd1", "site": "CorporateCareers"}},
15
+ {"slug": "hp", "name": "HP Inc.", "sector": "personal computing", "config": {"tenant": "hp", "env": "wd5", "site": "ExternalCareerSite"}},
16
+ {"slug": "wolterskluwer", "name": "Wolters Kluwer", "sector": "information services", "config": {"tenant": "wk", "env": "wd3", "site": "External"}},
17
+ {"slug": "mckesson", "name": "McKesson", "sector": "healthcare distribution", "config": {"tenant": "mckesson", "env": "wd3", "site": "External_Careers"}},
18
+ {"slug": "thehartford", "name": "The Hartford", "sector": "insurance", "config": {"tenant": "thehartford", "env": "wd5", "site": "Careers_External"}},
19
+ {"slug": "equifax", "name": "Equifax", "sector": "credit data", "config": {"tenant": "equifax", "env": "wd5", "site": "External"}},
20
+ {"slug": "zillow", "name": "Zillow Group", "sector": "real estate tech", "config": {"tenant": "zillow", "env": "wd5", "site": "Zillow_Group_External"}},
21
+ {"slug": "nationwide", "name": "Nationwide", "sector": "insurance / financial services", "config": {"tenant": "nationwide", "env": "wd1", "site": "Nationwide_Career"}},
22
+ {"slug": "toyota", "name": "Toyota Motor North America", "sector": "automotive", "config": {"tenant": "toyota", "env": "wd503", "site": "TMNA"}},
23
+ {"slug": "progressiveleasing", "name": "Progressive Leasing", "sector": "fintech / lease-to-own", "config": {"tenant": "progleasing", "env": "wd5", "site": "ProgLeasingCareers"}},
24
+ {"slug": "fico", "name": "FICO", "sector": "analytics / credit", "config": {"tenant": "fico", "env": "wd1", "site": "External"}},
25
+ {"slug": "sonyglobal", "name": "Sony Group", "sector": "electronics / entertainment", "config": {"tenant": "sonyglobal", "env": "wd1", "site": "SonyGlobalCareers"}},
26
+ {"slug": "sonypictures", "name": "Sony Pictures Entertainment", "sector": "media / entertainment", "config": {"tenant": "spe", "env": "wd1", "site": "SonyPicturesEntertainment"}},
27
+ {"slug": "merative", "name": "Merative", "sector": "health data", "config": {"tenant": "merative", "env": "wd12", "site": "External_Career_Site"}},
28
+ {"slug": "duckcreek", "name": "Duck Creek Technologies", "sector": "insurance software", "config": {"tenant": "duckcreek", "env": "wd1", "site": "duckcreekcareers"}}
29
+ ]
package/src/cli.js CHANGED
@@ -1,143 +1,190 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * jd-intel CLI
5
- *
6
- * Usage:
7
- * jd-intel fetch <company> [--ats greenhouse|lever|ashby] [--filter keyword|pattern]
8
- * jd-intel detect <company>
9
- * jd-intel registry search <query>
10
- */
11
-
12
- import { fetchJobs } from './index.js';
13
- import { detectAts, searchRegistry } from './registry.js';
14
-
15
- const [,, command, ...args] = process.argv;
16
-
17
- async function main() {
18
- switch (command) {
19
- case 'fetch': {
20
- const company = args[0];
21
- if (!company) { console.error('Usage: jd-intel fetch <company> [--ats greenhouse|lever|ashby]'); process.exit(1); }
22
- const getArg = (flag) => {
23
- const idx = args.indexOf(flag);
24
- return idx >= 0 ? args[idx + 1] : undefined;
25
- };
26
- const ats = getArg('--ats');
27
- const titleFilter = getArg('--title-filter');
28
- const filter = getArg('--filter');
29
- const postedWithinRaw = getArg('--posted-within-days');
30
- const postedWithinDays = postedWithinRaw !== undefined ? Number(postedWithinRaw) : undefined;
31
- const locIncludeRaw = getArg('--location-include');
32
- const locationIncludes = locIncludeRaw ? locIncludeRaw.split(',').map(s => s.trim()).filter(Boolean) : undefined;
33
- const locExcludeRaw = getArg('--location-exclude');
34
- const locationExcludes = locExcludeRaw ? locExcludeRaw.split(',').map(s => s.trim()).filter(Boolean) : undefined;
35
- const limitRaw = getArg('--limit');
36
- const limit = limitRaw !== undefined ? Number(limitRaw) : undefined;
37
-
38
- const parts = [];
39
- if (titleFilter) parts.push(`title: ${titleFilter}`);
40
- if (filter) parts.push(`topic: ${filter}`);
41
- if (postedWithinDays !== undefined) parts.push(`within ${postedWithinDays}d`);
42
- if (locationIncludes) parts.push(`loc+: ${locationIncludes.join('|')}`);
43
- if (locationExcludes) parts.push(`loc-: ${locationExcludes.join('|')}`);
44
- const suffix = parts.length ? ` [${parts.join(', ')}]` : '';
45
-
46
- console.log(`Fetching jobs from ${company}${ats ? ` (${ats})` : ' (auto-detect)'}${suffix}...`);
47
- const jobs = await fetchJobs({
48
- company, ats, titleFilter, filter, postedWithinDays, locationIncludes, locationExcludes, limit,
49
- });
50
- console.log(`Found ${jobs.length} jobs\n`);
51
-
52
- for (const job of jobs.slice(0, 20)) {
53
- const salary = job.salary ? ` | $${job.salary.min?.toLocaleString()}-$${job.salary.max?.toLocaleString()}` : '';
54
- const loc = job.location ? ` | ${job.location}` : '';
55
- const dept = job.department ? ` [${job.department}]` : '';
56
- console.log(` ${job.title}${dept}${loc}${salary}`);
57
- console.log(` ${job.url}`);
58
- if (job.description) {
59
- const preview = job.description.substring(0, 120).replace(/\n/g, ' ');
60
- console.log(` ${preview}...`);
61
- }
62
- console.log();
63
- }
64
-
65
- if (jobs.length > 20) {
66
- console.log(` ... and ${jobs.length - 20} more. Use --json for full output.`);
67
- }
68
-
69
- if (args.includes('--json')) {
70
- console.log(JSON.stringify(jobs, null, 2));
71
- }
72
- break;
73
- }
74
-
75
- case 'detect': {
76
- const company = args[0];
77
- if (!company) { console.error('Usage: jd-intel detect <company>'); process.exit(1); }
78
- console.log(`Detecting ATS for ${company}...`);
79
- const results = await detectAts(company);
80
- if (results.length === 0) {
81
- console.log('No ATS board found for this company.');
82
- } else {
83
- for (const r of results) {
84
- console.log(` Found: ${r.ats} (slug: ${r.slug})`);
85
- }
86
- }
87
- break;
88
- }
89
-
90
- case 'registry': {
91
- const subcommand = args[0];
92
- if (subcommand === 'search') {
93
- const query = args.slice(1).join(' ');
94
- if (!query) { console.error('Usage: jd-intel registry search <query>'); process.exit(1); }
95
- const results = await searchRegistry(query);
96
- console.log(`Found ${results.length} companies matching "${query}":\n`);
97
- for (const r of results) {
98
- console.log(` ${r.name || r.slug} (${r.ats})${r.sector ? ` — ${r.sector}` : ''}`);
99
- }
100
- } else {
101
- console.error('Usage: jd-intel registry search <query>');
102
- }
103
- break;
104
- }
105
-
106
- default:
107
- console.log(`jd-intel — JD intelligence toolkit for your AI assistant.
108
-
109
- Usage:
110
- jd-intel fetch <company> [options]
111
- jd-intel detect <company>
112
- jd-intel registry search <query>
113
-
114
- Fetch options:
115
- --ats greenhouse|lever|ashby Skip auto-detect
116
- --title-filter pattern Regex matched against TITLE only (role identity)
117
- --filter pattern Regex matched across title, department, description (topic/scope)
118
- --posted-within-days N Only jobs posted in the last N days
119
- --location-include "A,B,C" Keep jobs whose location contains any of these
120
- --location-exclude "A,B,C" Drop jobs whose location contains any of these
121
- --limit N Cap results (default 100)
122
- --json Output full JSON
123
-
124
- Filter guidance:
125
- Use --title-filter for "what KIND of role" (PM, engineer, designer).
126
- Use --filter for "what it's ABOUT" (integrations, growth, payments).
127
- Both AND together. Avoid --filter "product manager" — description
128
- mentions of PMs in other roles' JDs create false positives.
129
-
130
- Examples:
131
- jd-intel fetch stripe
132
- jd-intel fetch stripe --title-filter "product manager" --filter "growth|platform"
133
- jd-intel fetch ramp --location-include "United States,US,Remote - US" --location-exclude "London,Dublin"
134
- jd-intel fetch notion --ats ashby --title-filter engineer --posted-within-days 14
135
- jd-intel detect figma
136
- jd-intel registry search fintech`);
137
- }
138
- }
139
-
140
- main().catch(err => {
141
- console.error('Error:', err.message);
142
- process.exit(1);
143
- });
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * jd-intel CLI
5
+ *
6
+ * Usage:
7
+ * jd-intel fetch <company> [--ats <platform>] [--filter keyword|pattern]
8
+ * jd-intel detect <company>
9
+ * jd-intel registry search <query>
10
+ */
11
+
12
+ import { fetchJobs } from './index.js';
13
+ import { detectAts, searchRegistry } from './registry.js';
14
+
15
+ const [,, command, ...args] = process.argv;
16
+
17
+ async function main() {
18
+ switch (command) {
19
+ case 'fetch': {
20
+ const company = args[0];
21
+ if (!company) { console.error('Usage: jd-intel fetch <company> [--ats <platform>] (omit --ats to auto-detect; run "jd-intel" for the platform list)'); process.exit(1); }
22
+ const getArg = (flag) => {
23
+ const idx = args.indexOf(flag);
24
+ return idx >= 0 ? args[idx + 1] : undefined;
25
+ };
26
+ let ats = getArg('--ats');
27
+ const titleFilter = getArg('--title-filter');
28
+ const filter = getArg('--filter');
29
+ const postedWithinRaw = getArg('--posted-within-days');
30
+ const postedWithinDays = postedWithinRaw !== undefined ? Number(postedWithinRaw) : undefined;
31
+ const locIncludeRaw = getArg('--location-include');
32
+ const locationIncludes = locIncludeRaw ? locIncludeRaw.split(',').map(s => s.trim()).filter(Boolean) : undefined;
33
+ const locExcludeRaw = getArg('--location-exclude');
34
+ const locationExcludes = locExcludeRaw ? locExcludeRaw.split(',').map(s => s.trim()).filter(Boolean) : undefined;
35
+ const limitRaw = getArg('--limit');
36
+ const limit = limitRaw !== undefined ? Number(limitRaw) : undefined;
37
+
38
+ // Workday is keyed by a {tenant, env, site} triple, not a slug.
39
+ // Supplying it here makes a Workday board reachable without a
40
+ // registry entry; presence of the flags infers --ats workday.
41
+ const wdTenant = getArg('--workday-tenant');
42
+ const wdEnv = getArg('--workday-env');
43
+ const wdSite = getArg('--workday-site');
44
+ let config;
45
+ if (wdTenant || wdEnv || wdSite) {
46
+ if (!wdTenant || !wdEnv || !wdSite) {
47
+ console.error('Workday needs all three: --workday-tenant, --workday-env, --workday-site.');
48
+ console.error('Find them in the careers URL: https://{tenant}.{env}.myworkdayjobs.com/{site}');
49
+ console.error('e.g. https://expedia.wd108.myworkdayjobs.com/search -> --workday-tenant expedia --workday-env wd108 --workday-site search');
50
+ process.exit(1);
51
+ }
52
+ if (ats && ats !== 'workday') {
53
+ console.error(`--ats ${ats} conflicts with the --workday-* flags (workday is inferred). Drop one.`);
54
+ process.exit(1);
55
+ }
56
+ config = { tenant: wdTenant, env: wdEnv, site: wdSite };
57
+ ats = 'workday';
58
+ }
59
+
60
+ const parts = [];
61
+ if (titleFilter) parts.push(`title: ${titleFilter}`);
62
+ if (filter) parts.push(`topic: ${filter}`);
63
+ if (postedWithinDays !== undefined) parts.push(`within ${postedWithinDays}d`);
64
+ if (locationIncludes) parts.push(`loc+: ${locationIncludes.join('|')}`);
65
+ if (locationExcludes) parts.push(`loc-: ${locationExcludes.join('|')}`);
66
+ const suffix = parts.length ? ` [${parts.join(', ')}]` : '';
67
+
68
+ const atsLabel = config
69
+ ? ` (workday: ${config.tenant}/${config.env}/${config.site})`
70
+ : ats ? ` (${ats})` : ' (auto-detect)';
71
+ console.log(`Fetching jobs from ${company}${atsLabel}${suffix}...`);
72
+ let jobs;
73
+ try {
74
+ jobs = await fetchJobs({
75
+ company, ats, config, titleFilter, filter, postedWithinDays, locationIncludes, locationExcludes, limit,
76
+ });
77
+ } catch (err) {
78
+ if (config) {
79
+ console.error(`Could not reach that Workday board (${config.tenant}/${config.env}/${config.site}): ${err.message}`);
80
+ console.error('Verify the triple against the careers URL: https://{tenant}.{env}.myworkdayjobs.com/{site}');
81
+ process.exit(1);
82
+ }
83
+ throw err;
84
+ }
85
+ console.log(`Found ${jobs.length} jobs\n`);
86
+
87
+ for (const job of jobs.slice(0, 20)) {
88
+ const salary = job.salary ? ` | $${job.salary.min?.toLocaleString()}-$${job.salary.max?.toLocaleString()}` : '';
89
+ const loc = job.location ? ` | ${job.location}` : '';
90
+ const dept = job.department ? ` [${job.department}]` : '';
91
+ console.log(` ${job.title}${dept}${loc}${salary}`);
92
+ console.log(` ${job.url}`);
93
+ if (job.description) {
94
+ const preview = job.description.substring(0, 120).replace(/\n/g, ' ');
95
+ console.log(` ${preview}...`);
96
+ }
97
+ console.log();
98
+ }
99
+
100
+ if (jobs.length > 20) {
101
+ console.log(` ... and ${jobs.length - 20} more. Use --json for full output.`);
102
+ }
103
+
104
+ if (args.includes('--json')) {
105
+ console.log(JSON.stringify(jobs, null, 2));
106
+ }
107
+ break;
108
+ }
109
+
110
+ case 'detect': {
111
+ const company = args[0];
112
+ if (!company) { console.error('Usage: jd-intel detect <company>'); process.exit(1); }
113
+ console.log(`Detecting ATS for ${company}...`);
114
+ const results = await detectAts(company);
115
+ if (results.length === 0) {
116
+ console.log('No ATS board found for this company.');
117
+ } else {
118
+ for (const r of results) {
119
+ console.log(` Found: ${r.ats} (slug: ${r.slug})`);
120
+ }
121
+ }
122
+ break;
123
+ }
124
+
125
+ case 'registry': {
126
+ const subcommand = args[0];
127
+ if (subcommand === 'search') {
128
+ const query = args.slice(1).join(' ');
129
+ if (!query) { console.error('Usage: jd-intel registry search <query>'); process.exit(1); }
130
+ const results = await searchRegistry(query);
131
+ console.log(`Found ${results.length} companies matching "${query}":\n`);
132
+ for (const r of results) {
133
+ console.log(` ${r.name || r.slug} (${r.ats})${r.sector ? ` ${r.sector}` : ''}`);
134
+ }
135
+ } else {
136
+ console.error('Usage: jd-intel registry search <query>');
137
+ }
138
+ break;
139
+ }
140
+
141
+ default:
142
+ console.log(`jd-intel — JD intelligence toolkit for your AI assistant.
143
+
144
+ Usage:
145
+ jd-intel fetch <company> [options]
146
+ jd-intel detect <company>
147
+ jd-intel registry search <query>
148
+
149
+ Fetch options:
150
+ --ats <platform> Skip auto-detect. One of: greenhouse, lever,
151
+ ashby, smartrecruiters, teamtailor, recruitee,
152
+ workday. Omit to auto-detect (registry-backed).
153
+ --workday-tenant T Workday is keyed by a {tenant, env, site}
154
+ --workday-env wdN triple, not a slug. Registered Workday
155
+ --workday-site S companies work via auto-detect or --ats
156
+ workday; for any other Workday board pass
157
+ all three, read from the careers URL
158
+ https://{tenant}.{env}.myworkdayjobs.com/{site}
159
+ e.g. https://expedia.wd108.myworkdayjobs.com/search
160
+ -> --workday-tenant expedia --workday-env wd108
161
+ --workday-site search
162
+ --title-filter pattern Regex matched against TITLE only (role identity)
163
+ --filter pattern Regex matched across title, department, description (topic/scope)
164
+ --posted-within-days N Only jobs posted in the last N days
165
+ --location-include "A,B,C" Keep jobs whose location contains any of these
166
+ --location-exclude "A,B,C" Drop jobs whose location contains any of these
167
+ --limit N Cap results (default 100)
168
+ --json Output full JSON
169
+
170
+ Filter guidance:
171
+ Use --title-filter for "what KIND of role" (PM, engineer, designer).
172
+ Use --filter for "what it's ABOUT" (integrations, growth, payments).
173
+ Both AND together. Avoid --filter "product manager" — description
174
+ mentions of PMs in other roles' JDs create false positives.
175
+
176
+ Examples:
177
+ jd-intel fetch stripe
178
+ jd-intel fetch stripe --title-filter "product manager" --filter "growth|platform"
179
+ jd-intel fetch ramp --location-include "United States,US,Remote - US" --location-exclude "London,Dublin"
180
+ jd-intel fetch notion --ats ashby --title-filter engineer --posted-within-days 14
181
+ jd-intel fetch expedia --workday-tenant expedia --workday-env wd108 --workday-site search
182
+ jd-intel detect figma
183
+ jd-intel registry search fintech`);
184
+ }
185
+ }
186
+
187
+ main().catch(err => {
188
+ console.error('Error:', err.message);
189
+ process.exit(1);
190
+ });